Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/kwaroran/RisuAI
Browse files Browse the repository at this point in the history
  • Loading branch information
kwaroran committed Jan 1, 2025
2 parents 866996b + e977158 commit 821ba18
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 49 deletions.
6 changes: 3 additions & 3 deletions plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A plugin is a js file with a header. for example:

```js
//@name exampleplugin
//display-name: Example Plugin
//@display-name Example Plugin

// Plugin code here
```
Expand Down Expand Up @@ -118,7 +118,7 @@ Adds a risu script handler to the plugin.
- `type: string` - The handler type. one of `display`, `output`, `input`, `process`
- `display` - The handler will be called when the data is displayed.
- `output` - The handler will be called when the data is outputted by the AI model.
- `input` - The handler will be called when the data is inputted to the user.
- `input` - The handler will be called when the data is inputted by the user.
- `process` - The handler will be called when creating actual request data.
- `func: (content:string) => string|null|undefined|Promise<string|null|undefined>` - The handler function.
- `content: string` - The content to handle.
Expand Down Expand Up @@ -163,4 +163,4 @@ The plugin system has been updated to V2. The following changes have been made:
- `addCharaJs` function has been removed. use `addRisuScriptHandler` instead.
- `risuLog` function has been removed. use `console.log` instead.
- Many security restrictions have been removed.
- `@risu-name`, `@risu-display-name`, `@risu-arg` headers has been removed. use `@name`, `@display-name`, `@arg` instead. if it's not present, it will be ran as V1 plugin.
- `@risu-name`, `@risu-display-name`, `@risu-arg` headers has been removed. use `@name`, `@display-name`, `@arg` instead. if it's not present, it will be ran as V1 plugin.
1 change: 1 addition & 0 deletions src/lang/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ export const languageEnglish = {
cancel: "Cancel",
renameFolder: "Rename Folder",
changeFolderColor: "Change Folder Color",
changeFolderImage: "Change Folder Image",
fullWordMatching: "Full Word Matching",
botSettingAtStart: "Bot Menu when Launch",
triggerStart: "On chat Send",
Expand Down
1 change: 1 addition & 0 deletions src/lang/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ export const languageKorean = {
"cancel": "취소",
"renameFolder": "폴더 이름 변경하기",
"changeFolderColor": "폴더 색상 변경하기",
"changeFolderImage": "폴더 이미지 변경하기",
"fullWordMatching": "단어 단위 매칭",
"botSettingAtStart": "실행 시 봇 설정으로 시작하기",
"triggerStart": "채팅 보낼 시",
Expand Down
47 changes: 41 additions & 6 deletions src/lib/SideBars/Sidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@
import SidebarAvatar from "./SidebarAvatar.svelte";
import BaseRoundedButton from "../UI/BaseRoundedButton.svelte";
import { get } from "svelte/store";
import { getCharacterIndexObject } from "src/ts/util";
import { getCharacterIndexObject, selectSingleFile } from "src/ts/util";
import { v4 } from "uuid";
import { checkCharOrder } from "src/ts/globalApi.svelte";
import { checkCharOrder, getFileSrc, saveAsset } from "src/ts/globalApi.svelte";
import { alertInput, alertSelect } from "src/ts/alert";
import SideChatList from "./SideChatList.svelte";
import { ConnectionIsHost, ConnectionOpenStore, RoomIdStore } from "src/ts/sync/multiuser";
Expand All @@ -59,7 +59,7 @@
}
type sortTypeNormal = { type:'normal',img: string, index: number, name:string }
type sortType = sortTypeNormal|{type:'folder',folder:sortTypeNormal[],id:string, name:string, color:string}
type sortType = sortTypeNormal|{type:'folder',folder:sortTypeNormal[],id:string, name:string, color:string, img?:string}
let charImages: sortType[] = $state([]);
let IconRounded = $state(false)
let openFolders:string[] = $state([])
Expand Down Expand Up @@ -109,7 +109,8 @@
type: "folder",
id: folder.id,
name: folder.name,
color: folder.color
color: folder.color,
img: folder.img,
});
}
}
Expand Down Expand Up @@ -472,10 +473,10 @@
{:else if char.type === "folder"}
{#key char.color}
{#key char.name}
<SidebarAvatar src="slot" size="56" rounded={IconRounded} bordered name={char.name} color={char.color}
<SidebarAvatar src="slot" size="56" rounded={IconRounded} bordered name={char.name} color={char.color} backgroundimg={char.img}
oncontextmenu={async (e) => {
e.preventDefault()
const sel = parseInt(await alertSelect([language.renameFolder,language.changeFolderColor,language.cancel]))
const sel = parseInt(await alertSelect([language.renameFolder,language.changeFolderColor,language.changeFolderImage,language.cancel]))
if(sel === 0){
const v = await alertInput(language.changeFolderName)
const db = DBState.db
Expand All @@ -501,6 +502,40 @@
db.characterOrder[ind] = oder
setDatabase(db)
}
else if(sel === 2) {
const sel = parseInt(await alertSelect(['Reset to Default Image', 'Select Image File']))
const db = DBState.db
const oder = db.characterOrder[ind]
if(typeof(oder) === 'string'){
return
}

switch (sel) {
case 0:
oder.imgFile = null
oder.img = ''
break;

case 1:
const folderImage = await selectSingleFile([
'png',
'jpg',
'webp',
])

if(!folderImage) {
return
}

const folderImageData = await saveAsset(folderImage.data)

oder.imgFile = folderImageData
oder.img = await getFileSrc(folderImageData)
db.characterOrder[ind] = oder
setDatabase(db)
break;
}
}
}}
onClick={() => {
if(char.type !== 'folder'){
Expand Down
11 changes: 10 additions & 1 deletion src/lib/SideBars/SidebarAvatar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
onClick?: any;
bordered?: boolean;
color?: string;
backgroundimg?: string;
children?: import('svelte').Snippet;
oncontextmenu?: (event: MouseEvent & {
currentTarget: EventTarget & HTMLDivElement;
Expand All @@ -23,6 +24,7 @@
onClick = () => {},
bordered = false,
color = '',
backgroundimg = '',
children,
oncontextmenu
}: Props = $props();
Expand Down Expand Up @@ -55,8 +57,15 @@
style:width={size + "px"}
style:height={size + "px"}
style:minWidth={size + "px"}
style:background-image={backgroundimg ? `url('${backgroundimg}')` : undefined}
style:background-size={backgroundimg ? "cover" : undefined}
style:background-position={backgroundimg ? "center" : undefined}
class:rounded-md={!rounded} class:rounded-full={rounded}
>{@render children?.()}</div>
>
{#if !backgroundimg}
{@render children?.()}
{/if}
</div>
{:else}
{#await src}
<div
Expand Down
8 changes: 8 additions & 0 deletions src/ts/globalApi.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,14 @@ export function getUnpargeables(db: Database, uptype: 'basename' | 'pure' = 'bas
addUnparge(v.icon);
});
}

if(db.characterOrder){
db.characterOrder.forEach((item) => {
if (typeof item === 'object' && 'imgFile' in item) {
addUnparge(item.imgFile);
}
})
}
return unpargeable;
}

Expand Down
3 changes: 2 additions & 1 deletion src/ts/plugins/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,8 @@ export async function loadV2Plugin(plugins:RisuPlugin[]){
const getChar = globalThis.__pluginApis__.getChar
const setChar = globalThis.__pluginApis__.setChar
const addProvider = globalThis.__pluginApis__.addProvider
const addRisuEventHandler = globalThis.__pluginApis__.addRisuEventHandler
const addRisuScriptHandler = globalThis.__pluginApis__.addRisuScriptHandler
const removeRisuScriptHandler = globalThis.__pluginApis__.removeRisuScriptHandler
const addRisuReplacer = globalThis.__pluginApis__.addRisuReplacer
const removeRisuReplacer = globalThis.__pluginApis__.removeRisuReplacer
const onUnload = globalThis.__pluginApis__.onUnload
Expand Down
74 changes: 36 additions & 38 deletions src/ts/process/memory/hypav2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,23 +317,29 @@ export async function hypaMemoryV2(
const data: HypaV2Data = room.hypaV2Data ?? {
lastMainChunkID: 0,
chunks: [],
mainChunks: []
mainChunks: [],
};
// JSON s
data.mainChunks.forEach(mainChunk => {
if (mainChunk.chatMemos && Array.isArray(mainChunk.chatMemos)) {
mainChunk.chatMemos = new Set(mainChunk.chatMemos);
}
});

// Clean invalid HypaV2 data
cleanInvalidChunks(chats, data);

let allocatedTokens = db.hypaAllocatedTokens;
let chunkSize = db.hypaChunkSize;
currentTokens += allocatedTokens + chats.length * 4; // ChatML token counting from official openai documentation
currentTokens += allocatedTokens; // WARNING: VIRTUAL VALUE. This token is NOT real. This is a placeholder appended to calculate the maximum amount of HypaV2 memory retrieved data.
let mainPrompt = "";
const lastTwoChats = chats.slice(-2);
// Error handling for infinite summarization attempts
// Error handling for failed summarization
let summarizationFailures = 0;
const maxSummarizationFailures = 3;

// Find the index to start summarizing from
let idx = 2; // first two should not be considered
let idx = 2; // first two should not be considered([Start a new chat], Memory prompt)
if (data.mainChunks.length > 0) {
const lastMainChunk = data.mainChunks[data.mainChunks.length - 1];
const lastChatMemo = lastMainChunk.lastChatMemo;
Expand All @@ -345,14 +351,14 @@ export async function hypaMemoryV2(
// Starting chat index of new mainChunk to be generated

// Token management loop (If current token usage exceeds allowed amount)
while (currentTokens >= maxContextTokens) {
while (currentTokens > maxContextTokens) {
const halfData: OpenAIChat[] = [];
let halfDataTokens = 0;

const startIdx = idx;

console.log(
"Starting summarization iteration:",
"[HypaV2] Starting summarization iteration:",
"\nCurrent Tokens (before):", currentTokens,
"\nMax Context Tokens:", maxContextTokens,
"\nStartIdx:", startIdx,
Expand All @@ -362,13 +368,13 @@ export async function hypaMemoryV2(
// Accumulate chats to summarize
while (
halfDataTokens < chunkSize &&
idx < chats.length - 2 // keep the last two chats from summarizing(else, the roles will be fucked up)
(idx < chats.length - 4) // keep the last two chats from summarizing(else, the roles will be fucked up)
) {
const chat = chats[idx];
const chatTokens = await tokenizer.tokenizeChat(chat);

console.log(
"Evaluating chat for summarization:",
"[HypaV2] Evaluating chat for summarization:",
"\nIndex:", idx,
"\nRole:", chat.role,
"\nContent:", chat.content,
Expand All @@ -392,7 +398,7 @@ export async function hypaMemoryV2(

const endIdx = idx - 1;
console.log(
"Summarization batch chosen with this:",
"[HypaV2] Summarization batch chosen with this:",
"\nStartIdx:", startIdx,
"\nEndIdx:", endIdx,
"\nNumber of chats in halfData:", halfData.length,
Expand All @@ -402,7 +408,7 @@ export async function hypaMemoryV2(

// If no chats were added, break to avoid infinite loop
if (halfData.length === 0) {
console.log("No chats to summarize in this iteration, breaking out.");
console.log("HOW DID WE GET HERE???");
break;
}

Expand Down Expand Up @@ -436,27 +442,11 @@ export async function hypaMemoryV2(
});

console.log(
"Summarization success:",
"[HypaV2] Summarization success:",
"\nSummary Data:", summaryData.data,
"\nSummary Token Count:", summaryDataToken
);

// **Token accounting fix:**
// Previous commits, the code likely have missed removing summarized chat's tokens.
// and never actually accounted for adding the summary tokens.
// Now we:
// 1. Remove old chats' tokens (they are replaced by summary)
// 2. Add summary tokens instead
currentTokens -= halfDataTokens; // remove original chats' tokens
currentTokens += summaryDataToken; // add the summary's tokens

console.log(
"After token adjustment:",
"\nRemoved halfDataTokens:", halfDataTokens,
"\nAdded summaryDataToken:", summaryDataToken,
"\nCurrent Tokens (after):", currentTokens
);

// Update lastMainChunkID and create a new mainChunk
data.lastMainChunkID++;
const newMainChunkId = data.lastMainChunkID;
Expand Down Expand Up @@ -485,11 +475,14 @@ export async function hypaMemoryV2(
);

console.log(
"Chunks added:",
"[HypaV2] Chunks added:",
splitted,
"\nUpdated mainChunks count:", data.mainChunks.length,
"\nUpdated chunks count:", data.chunks.length
);

currentTokens -= halfDataTokens;
console.log("[HypaV2] tokens after summarization deduction:", currentTokens);
}

// Construct the mainPrompt from mainChunks
Expand Down Expand Up @@ -557,28 +550,33 @@ export async function hypaMemoryV2(
}

const fullResult = `<Past Events Summary>${mainPrompt}</Past Events Summary>\n<Past Events Details>${chunkResultPrompts}</Past Events Details>`;

// Filter out summarized chats
const unsummarizedChats = chats.slice(idx);

// Insert the memory system prompt at the beginning
unsummarizedChats.unshift({
const fullResultTokens = await tokenizer.tokenizeChat({
role: "system",
content: fullResult,
memo: "supaMemory",
});
currentTokens += fullResultTokens;

// Filter out summarized chats and prepend the memory prompt
const unsummarizedChats: OpenAIChat[] = [
{
role: "system",
content: fullResult,
memo: "supaMemory",
},
...chats.slice(idx) // Use the idx to slice out the summarized chats
];

// Remove this later, as this is already done by the index
for (const chat of lastTwoChats) {
if (!unsummarizedChats.find((c) => c.memo === chat.memo)) {
unsummarizedChats.push(chat);
}
}

// Recalculate currentTokens
currentTokens = await tokenizer.tokenizeChats(unsummarizedChats);
currentTokens -= allocatedTokens; // Virtually added memory tokens got removed. Bad way, but had no choice.

console.log(
"Model being used: ",
"[HypaV2] Model being used: ",
db.hypaModel,
db.supaModelType,
"\nCurrent session tokens: ",
Expand Down
1 change: 1 addition & 0 deletions src/ts/process/tts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ export async function sayTTS(character:character,text:string) {
const text = Buffer.from(textBuffer).toString('utf-8')
throw new Error(text);
}
break;
}
case 'fishspeech':{
if (character.fishSpeechConfig.model._id === ''){
Expand Down
2 changes: 2 additions & 0 deletions src/ts/storage/database.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,8 @@ export interface folder{
data:string[]
color:string
id:string
imgFile?:string
img?:string
}


Expand Down

0 comments on commit 821ba18

Please sign in to comment.