Add autopilot

This commit is contained in:
kwaroran
2024-09-01 19:30:06 +09:00
parent de6c90cbc4
commit ccda92cc49
2 changed files with 182 additions and 9 deletions

View File

@@ -1,13 +1,22 @@
<script lang="ts">
import { CurrentChat } from "src/ts/stores";
import TextInput from "../UI/GUI/TextInput.svelte";
import NumberInput from "../UI/GUI/NumberInput.svelte";
import Button from "../UI/GUI/Button.svelte";
import { getRequestLog } from "src/ts/storage/globalApi";
import { alertMd } from "src/ts/alert";
import Arcodion from "../UI/Arcodion.svelte";
import { CurrentCharacter, CurrentChat, selectedCharID } from "src/ts/stores";
import TextInput from "../UI/GUI/TextInput.svelte";
import NumberInput from "../UI/GUI/NumberInput.svelte";
import Button from "../UI/GUI/Button.svelte";
import { getRequestLog } from "src/ts/storage/globalApi";
import { alertMd } from "src/ts/alert";
import Arcodion from "../UI/Arcodion.svelte";
import { getCharToken, getChatToken } from "src/ts/tokenizer";
import { tokenizePreset } from "src/ts/process/prompt";
import { DataBase, setDatabase } from "src/ts/storage/database";
import TextAreaInput from "../UI/GUI/TextAreaInput.svelte";
import { FolderUpIcon, PlusIcon, TrashIcon } from "lucide-svelte";
import { selectSingleFile } from "src/ts/util";
import { file } from "jszip";
import { doingChat, sendChat } from "src/ts/process";
let autopilot = []
</script>
<Arcodion styled name={"Variables"}>
@@ -29,6 +38,116 @@
</div>
</Arcodion>
<Button on:click={() => {
<Arcodion styled name={"Tokens"}>
<div class="rounded-md border border-darkborderc grid grid-cols-2 gap-2 p-2">
{#await getCharToken($CurrentCharacter)}
<span>Character Persistant</span>
<div class="p-2 text-center">Loading...</div>
<span>Character Dynamic</span>
<div class="p-2 text-center">Loading...</div>
{:then token}
<span>Character Persistant</span>
<div class="p-2 text-center">{token.persistant} Tokens</div>
<span>Character Dynamic</span>
<div class="p-2 text-center">{token.dynamic} Tokens</div>
{/await}
{#await getChatToken($CurrentChat)}
<span>Current Chat</span>
<div class="p-2 text-center">Loading...</div>
{:then token}
<span>Current Chat</span>
<div class="p-2 text-center">{token} Tokens</div>
{/await}
{#if $DataBase.promptTemplate}
{#await tokenizePreset($DataBase.promptTemplate)}
<span>Prompt Template</span>
<div class="p-2 text-center">Loading...</div>
{:then token}
<span>Prompt Template</span>
<div class="p-2 text-center">{token} Tokens</div>
{/await}
{/if}
</div>
<span class="text-sm text-textcolor2">This is a estimate. The actual token count may be different.</span>
</Arcodion>
<Arcodion styled name={"Autopilot"}>
<div class="flex flex-col p-2 border border-darkborderc rounded-md">
{#each autopilot as text}
<TextAreaInput bind:value={text} />
{/each}
</div>
<div class="flex justify-end">
<button class="text-textcolor2 hover:text-textcolor" on:click={() => {
autopilot.pop()
autopilot = autopilot
}}>
<TrashIcon />
</button>
<button class="text-textcolor2 hover:text-textcolor" on:click={() => {
autopilot.push('')
autopilot = autopilot
}}>
<PlusIcon />
</button>
<button class="text-textcolor2 hover:text-textcolor" on:click={async () => {
const selected = await selectSingleFile([
'txt', 'csv', 'json'
])
if(!selected){
return
}
const file = new TextDecoder().decode(selected.data)
if(selected.name.endsWith('.json')){
const parsed = JSON.parse(file)
if(Array.isArray(parsed)){
autopilot = parsed
}
}
if(selected.name.endsWith('.csv')){
autopilot = file.split('\n').map(x => {
return x.replace(/\r/g, '')
.replace(/\\n/g, '\n')
.replace(/\\t/g, '\t')
.replace(/\\r/g, '\r')
})
}
if(selected.name.endsWith('.txt')){
autopilot = file.split('\n')
}
}}>
<FolderUpIcon />
</button>
</div>
<Button className="mt-2" on:click={async () => {
if($doingChat){
return
}
for(let i=0;i<autopilot.length;i++){
const db = ($DataBase)
let currentChar = db.characters[$selectedCharID]
let currentChat = currentChar.chats[currentChar.chatPage]
currentChat.message.push({
role: 'user',
data: autopilot[i]
})
currentChar.chats[currentChar.chatPage] = currentChat
db.characters[$selectedCharID] = currentChar
if($doingChat){
return
}
currentChar.chats[currentChar.chatPage] = currentChat
db.characters[$selectedCharID] = currentChar
doingChat.set(false)
await sendChat(i);
currentChar = db.characters[$selectedCharID]
currentChat = currentChar.chats[currentChar.chatPage]
}
doingChat.set(false)
}}>Run</Button>
</Arcodion>
<Button className="mt-2" on:click={() => {
alertMd(getRequestLog())
}}>Request Log</Button>

View File

@@ -1,12 +1,13 @@
import type { Tiktoken } from "@dqbd/tiktoken";
import type { Tokenizer } from "@mlc-ai/web-tokenizers";
import { DataBase, type character } from "./storage/database";
import { DataBase, type groupChat, type character, type Chat } from "./storage/database";
import { get } from "svelte/store";
import type { MultiModal, OpenAIChat } from "./process";
import { supportsInlayImage } from "./process/files/image";
import { risuChatParser } from "./parser";
import { tokenizeGGUFModel } from "./process/models/local";
import { globalFetch } from "./storage/globalApi";
import { CurrentCharacter } from "./stores";
export const tokenizerList = [
@@ -342,4 +343,57 @@ export async function strongBan(data:string, bias:{[key:number]:number}) {
}
localStorage.setItem('strongBan_' + data, JSON.stringify(bias))
return bias
}
export async function getCharToken(char?:character|groupChat|null){
let persistant = 0
let dynamic = 0
if(!char){
const c = get(CurrentCharacter)
char = c
}
if(char.type === 'group'){
return {persistant:0, dynamic:0}
}
const basicTokenize = async (data:string) => {
data = data.replace(/{{char}}/g, char.name).replace(/<char>/g, char.name)
return await tokenize(data)
}
persistant += await basicTokenize(char.desc)
persistant += await basicTokenize(char.personality ?? '')
persistant += await basicTokenize(char.scenario ?? '')
for(const lore of char.globalLore){
let cont = lore.content.split('\n').filter((line) => {
if(line.startsWith('@@')){
return false
}
if(line === ''){
return false
}
return true
}).join('\n')
dynamic += await basicTokenize(cont)
}
return {persistant, dynamic}
}
export async function getChatToken(chat:Chat) {
let persistant = 0
const chatTokenizer = new ChatTokenizer(0, 'name')
const chatf = chat.message.map((d) => {
return {
role: d.role === 'user' ? 'user' : 'assistant',
content: d.data,
} as OpenAIChat
})
for(const chat of chatf){
persistant += await chatTokenizer.tokenizeChat(chat)
}
return persistant
}