Update to 1.16.0 (#96)
This commit is contained in:
1
public/icon/github-mark-white.svg
Normal file
1
public/icon/github-mark-white.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg width="98" height="96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#fff"/></svg>
|
||||||
|
After Width: | Height: | Size: 960 B |
BIN
public/icon/patreon.png
Normal file
BIN
public/icon/patreon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
@@ -8,7 +8,7 @@
|
|||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "RisuAI",
|
"productName": "RisuAI",
|
||||||
"version": "1.15.6"
|
"version": "1.16.0"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": {
|
"allowlist": {
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export const languageEnglish = {
|
|||||||
+ "\n\n```<START>``` Marks the beginning of a new conversation.",
|
+ "\n\n```<START>``` Marks the beginning of a new conversation.",
|
||||||
creatorQuotes: "Note that appearances on top of first message. Used to inform users about this character. It doesn't go into prompt.",
|
creatorQuotes: "Note that appearances on top of first message. Used to inform users about this character. It doesn't go into prompt.",
|
||||||
systemPrompt: "A prompt that replaces main prompt in settings if its not blank.",
|
systemPrompt: "A prompt that replaces main prompt in settings if its not blank.",
|
||||||
chatNote: "a note that strongly effects model behavior. embbedded to current chat. also known as memory.",
|
chatNote: "a note that strongly effects model behavior. embbedded to current chat. also known as memory or ujb.",
|
||||||
personality: "A brief description about character's personality. \n\n**It is not recommended to use this option. Describe it in character description instead.**",
|
personality: "A brief description about character's personality. \n\n**It is not recommended to use this option. Describe it in character description instead.**",
|
||||||
scenario: "A brief description about character's scenario. \n\n**It is not recommended to use this option. Describe it in character description instead.**",
|
scenario: "A brief description about character's scenario. \n\n**It is not recommended to use this option. Describe it in character description instead.**",
|
||||||
utilityBot: "When activated, it ignores main prompt. \n\n**It is not recommended to use this option. Modifiy system prompt instead.**",
|
utilityBot: "When activated, it ignores main prompt. \n\n**It is not recommended to use this option. Modifiy system prompt instead.**",
|
||||||
@@ -76,7 +76,8 @@ export const languageEnglish = {
|
|||||||
superMemory: "SuperMemory makes your character memorize more by giving summarized data to AI.\n\n"
|
superMemory: "SuperMemory makes your character memorize more by giving summarized data to AI.\n\n"
|
||||||
+ "SuperMemory model is a model that summarizes that text. davinci is recommended, and Auxiliary models are not recommended unless it is an unfiltered model with over 2000 tokens with great summarizing skill.\n\n"
|
+ "SuperMemory model is a model that summarizes that text. davinci is recommended, and Auxiliary models are not recommended unless it is an unfiltered model with over 2000 tokens with great summarizing skill.\n\n"
|
||||||
+ "SuperMemory Prompt decides what prompt should be sent to summarize. if you leave it blank, it will use the default prompt. leaving blank is recommended.\n\n"
|
+ "SuperMemory Prompt decides what prompt should be sent to summarize. if you leave it blank, it will use the default prompt. leaving blank is recommended.\n\n"
|
||||||
+ "After it is all setup, you can able it in the setting of a character."
|
+ "After it is all setup, you can able it in the setting of a character.",
|
||||||
|
replaceGlobalNote: "If its not blank, it replaces current global note to this."
|
||||||
},
|
},
|
||||||
setup: {
|
setup: {
|
||||||
chooseProvider: "Choose AI Provider",
|
chooseProvider: "Choose AI Provider",
|
||||||
@@ -266,5 +267,8 @@ export const languageEnglish = {
|
|||||||
textScreenBorder: "Text Screen Borders",
|
textScreenBorder: "Text Screen Borders",
|
||||||
ttsReadOnlyQuoted: "Read Only Quoted",
|
ttsReadOnlyQuoted: "Read Only Quoted",
|
||||||
ttsStop: "Stop TTS",
|
ttsStop: "Stop TTS",
|
||||||
askRemoval:"Ask Removal"
|
askRemoval:"Ask Removal",
|
||||||
|
replaceGlobalNote: "Global Note Replacement",
|
||||||
|
charLoreBook: 'Character Lorebook',
|
||||||
|
globalLoreBook: 'Global Lorebook',
|
||||||
}
|
}
|
||||||
@@ -246,6 +246,9 @@ export const languageKorean = {
|
|||||||
textScreenBorder: "채팅창 윤곽선",
|
textScreenBorder: "채팅창 윤곽선",
|
||||||
ttsReadOnlyQuoted: "따옴표 안 텍스트만 읽기",
|
ttsReadOnlyQuoted: "따옴표 안 텍스트만 읽기",
|
||||||
ttsStop: "TTS 중지",
|
ttsStop: "TTS 중지",
|
||||||
askRemoval:"삭제 확인"
|
askRemoval:"삭제 확인",
|
||||||
|
replaceGlobalNote: "글로벌 노트 덮어쓰기",
|
||||||
|
charLoreBook: '캐릭터 로어북',
|
||||||
|
globalLoreBook: '글로벌 로어북',
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,24 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { isTauri } from "src/ts/globalApi";
|
import { isTauri, openURL } from "src/ts/globalApi";
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<script async defer src="https://buttons.github.io/buttons.js"></script>
|
<script async defer src="https://buttons.github.io/buttons.js"></script>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
<!-- Place this tag where you want the button to render. -->
|
|
||||||
{#if !isTauri}
|
<div class="flex gap-2 items-center mt-2">
|
||||||
|
{#if !isTauri}
|
||||||
<a class="github-button mt-4" href="https://github.com/kwaroran/risuAI" data-color-scheme="no-preference: dark; light: dark; dark: dark;" data-size="large" data-show-count="true" aria-label="Star kwaroran/risuAI on GitHub">Star</a>
|
<a class="github-button mt-4" href="https://github.com/kwaroran/risuAI" data-color-scheme="no-preference: dark; light: dark; dark: dark;" data-size="large" data-show-count="true" aria-label="Star kwaroran/risuAI on GitHub">Star</a>
|
||||||
{/if}
|
{:else}
|
||||||
|
<button on:click={() => {
|
||||||
|
openURL("https://github.com/kwaroran/risuAI")
|
||||||
|
}}>
|
||||||
|
<img src="/icon/github-mark-white.svg" width="24" alt="github" />
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
<button on:click={() => {
|
||||||
|
openURL("https://www.patreon.com/RisuAI")
|
||||||
|
}}>
|
||||||
|
<img src="/icon/patreon.png" width="24" alt="github" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
import { customProviderStore, getCurrentPluginMax } from "src/ts/process/plugins";
|
import { customProviderStore, getCurrentPluginMax } from "src/ts/process/plugins";
|
||||||
import { isTauri } from "src/ts/globalApi";
|
import { isTauri } from "src/ts/globalApi";
|
||||||
import { tokenize } from "src/ts/tokenizer";
|
import { tokenize } from "src/ts/tokenizer";
|
||||||
|
import ModelList from "src/lib/UI/ModelList.svelte";
|
||||||
import DropList from "src/lib/SideBars/DropList.svelte";
|
import DropList from "src/lib/SideBars/DropList.svelte";
|
||||||
import { PlusIcon, TrashIcon } from "lucide-svelte";
|
import { PlusIcon, TrashIcon } from "lucide-svelte";
|
||||||
let tokens = {
|
let tokens = {
|
||||||
@@ -36,26 +37,10 @@
|
|||||||
|
|
||||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.chatBot}</h2>
|
<h2 class="mb-2 text-2xl font-bold mt-2">{language.chatBot}</h2>
|
||||||
<span class="text-neutral-200 mt-4">{language.model} <Help key="model"/></span>
|
<span class="text-neutral-200 mt-4">{language.model} <Help key="model"/></span>
|
||||||
<select class="bg-transparent input-text mt-2 mb-2 text-gray-200 appearance-none text-sm" bind:value={$DataBase.aiModel}>
|
<ModelList bind:value={$DataBase.aiModel}/>
|
||||||
<option value="gpt35" class="bg-darkbg appearance-none">OpenAI GPT-3.5</option>
|
|
||||||
<option value="gpt4" class="bg-darkbg appearance-none">OpenAI GPT-4</option>
|
|
||||||
<option value="textgen_webui" class="bg-darkbg appearance-none">Text Generation WebUI</option>
|
|
||||||
<option value="palm2" class="bg-darkbg appearance-none">Google Palm2</option>
|
|
||||||
{#if $DataBase.plugins.length > 0}
|
|
||||||
<option value="custom" class="bg-darkbg appearance-none">Plugin</option>
|
|
||||||
{/if}
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<span class="text-neutral-200 mt-2">{language.submodel} <Help key="submodel"/></span>
|
<span class="text-neutral-200 mt-2">{language.submodel} <Help key="submodel"/></span>
|
||||||
<select class="bg-transparent input-text mt-2 mb-4 text-gray-200 appearance-none text-sm" bind:value={$DataBase.subModel}>
|
<ModelList bind:value={$DataBase.subModel}/>
|
||||||
<option value="gpt35" class="bg-darkbg appearance-none">OpenAI GPT-3.5</option>
|
|
||||||
<option value="gpt4" class="bg-darkbg appearance-none">OpenAI GPT-4</option>
|
|
||||||
<option value="palm2" class="bg-darkbg appearance-none">Google Palm2</option>
|
|
||||||
<option value="textgen_webui" class="bg-darkbg appearance-none">Text Generation WebUI</option>
|
|
||||||
{#if $customProviderStore.length > 0}
|
|
||||||
<option value="custom" class="bg-darkbg appearance-none">Plugin</option>
|
|
||||||
{/if}
|
|
||||||
</select>
|
|
||||||
|
|
||||||
{#if $DataBase.aiModel === 'palm2' || $DataBase.subModel === 'palm2'}
|
{#if $DataBase.aiModel === 'palm2' || $DataBase.subModel === 'palm2'}
|
||||||
<span class="text-neutral-200">Palm2 {language.apiKey}</span>
|
<span class="text-neutral-200">Palm2 {language.apiKey}</span>
|
||||||
@@ -78,6 +63,17 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if $DataBase.aiModel === "novelai" || $DataBase.subModel === "novelai"}
|
||||||
|
<span class="text-neutral-200">NovelAI Bearer Token</span>
|
||||||
|
<input class="text-neutral-200 p-2 bg-transparent input-text focus:bg-selected text-sm mb-2" bind:value={$DataBase.novelai.token}>
|
||||||
|
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if $DataBase.aiModel.startsWith("horde") || $DataBase.subModel.startsWith("horde") }
|
||||||
|
<span class="text-neutral-200">Horde {language.apiKey}</span>
|
||||||
|
<input class="text-neutral-200 p-2 bg-transparent input-text focus:bg-selected text-sm mb-2" bind:value={$DataBase.hordeConfig.apiKey}>
|
||||||
|
|
||||||
|
{/if}
|
||||||
{#if $DataBase.aiModel === 'textgen_webui' || $DataBase.subModel === 'textgen_webui'}
|
{#if $DataBase.aiModel === 'textgen_webui' || $DataBase.subModel === 'textgen_webui'}
|
||||||
<span class="text-neutral-200">TextGen {language.providerURL} <Help key="oogaboogaURL"/></span>
|
<span class="text-neutral-200">TextGen {language.providerURL} <Help key="oogaboogaURL"/></span>
|
||||||
<input class="text-neutral-200 mb-4 p-2 bg-transparent input-text focus:bg-selected" placeholder="https://..." bind:value={$DataBase.textgenWebUIURL}>
|
<input class="text-neutral-200 mb-4 p-2 bg-transparent input-text focus:bg-selected" placeholder="https://..." bind:value={$DataBase.textgenWebUIURL}>
|
||||||
@@ -98,12 +94,15 @@
|
|||||||
|
|
||||||
<span class="text-gray-400 mb-6 text-sm">{tokens.globalNote} {language.tokens}</span>
|
<span class="text-gray-400 mb-6 text-sm">{tokens.globalNote} {language.tokens}</span>
|
||||||
<span class="text-neutral-200">{language.maxContextSize}</span>
|
<span class="text-neutral-200">{language.maxContextSize}</span>
|
||||||
|
|
||||||
{#if $DataBase.aiModel === 'gpt35'}
|
{#if $DataBase.aiModel === 'gpt35'}
|
||||||
<input class="text-neutral-200 mb-4 text-sm p-2 bg-transparent input-text focus:bg-selected" type="number" min={0} max="4000" bind:value={$DataBase.maxContext}>
|
<input class="text-neutral-200 mb-4 text-sm p-2 bg-transparent input-text focus:bg-selected" type="number" min={0} max="4000" bind:value={$DataBase.maxContext}>
|
||||||
{:else if $DataBase.aiModel === 'gpt4' || $DataBase.aiModel === 'textgen_webui'}
|
{:else if $DataBase.aiModel === 'gpt4' || $DataBase.aiModel === 'textgen_webui'}
|
||||||
<input class="text-neutral-200 mb-4 text-sm p-2 bg-transparent input-text focus:bg-selected" type="number" min={0} max="8000" bind:value={$DataBase.maxContext}>
|
<input class="text-neutral-200 mb-4 text-sm p-2 bg-transparent input-text focus:bg-selected" type="number" min={0} max="8000" bind:value={$DataBase.maxContext}>
|
||||||
{:else if $DataBase.aiModel === 'custom'}
|
{:else if $DataBase.aiModel === 'custom'}
|
||||||
<input class="text-neutral-200 mb-4 text-sm p-2 bg-transparent input-text focus:bg-selected" type="number" min={0} max={getCurrentPluginMax($DataBase.currentPluginProvider)} bind:value={$DataBase.maxContext}>
|
<input class="text-neutral-200 mb-4 text-sm p-2 bg-transparent input-text focus:bg-selected" type="number" min={0} max={getCurrentPluginMax($DataBase.currentPluginProvider)} bind:value={$DataBase.maxContext}>
|
||||||
|
{:else}
|
||||||
|
<input class="text-neutral-200 mb-4 text-sm p-2 bg-transparent input-text focus:bg-selected" type="number" min={0} bind:value={$DataBase.maxContext}>
|
||||||
{/if}
|
{/if}
|
||||||
<span class="text-neutral-200">{language.maxResponseSize}</span>
|
<span class="text-neutral-200">{language.maxResponseSize}</span>
|
||||||
<input class="text-neutral-200 mb-4 p-2 bg-transparent input-text focus:bg-selected text-sm" type="number" min={0} max="2048" bind:value={$DataBase.maxResponse}>
|
<input class="text-neutral-200 mb-4 p-2 bg-transparent input-text focus:bg-selected text-sm" type="number" min={0} max="2048" bind:value={$DataBase.maxResponse}>
|
||||||
|
|||||||
11
src/lib/Setting/Pages/GlobalLoreBookSettings.svelte
Normal file
11
src/lib/Setting/Pages/GlobalLoreBookSettings.svelte
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { language } from "src/lang";
|
||||||
|
import Help from "src/lib/Others/Help.svelte";
|
||||||
|
import LoreBookSetting from "src/lib/SideBars/LoreBookSetting.svelte";
|
||||||
|
import { DataBase } from "src/ts/database";
|
||||||
|
export let openLoreList = false
|
||||||
|
</script>
|
||||||
|
<h2 class="mb-2 text-2xl font-bold mt-2">{language.globalLoreBook} <Help key="lorebook" /></h2>
|
||||||
|
<button on:click={() => {openLoreList = true}} class="mt-4 drop-shadow-lg p-3 flex justify-center items-center ml-2 mr-2 rounded-lg bg-selected mb-4">{$DataBase.loreBook[$DataBase.loreBookPage].name}</button>
|
||||||
|
|
||||||
|
<LoreBookSetting globalMode />
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ActivityIcon, BotIcon, BoxIcon, CodeIcon, DiamondIcon, FolderIcon, MonitorIcon, Sailboat, UserIcon, XCircleIcon } from "lucide-svelte";
|
import { ActivityIcon, BookIcon, BotIcon, BoxIcon, CodeIcon, DiamondIcon, FolderIcon, MonitorIcon, Sailboat, UserIcon, XCircleIcon } from "lucide-svelte";
|
||||||
import { language } from "src/lang";
|
import { language } from "src/lang";
|
||||||
import DisplaySettings from "./Pages/DisplaySettings.svelte";
|
import DisplaySettings from "./Pages/DisplaySettings.svelte";
|
||||||
import UserSettings from "./Pages/UserSettings.svelte";
|
import UserSettings from "./Pages/UserSettings.svelte";
|
||||||
@@ -8,12 +8,14 @@
|
|||||||
import PluginSettings from "./Pages/PluginSettings.svelte";
|
import PluginSettings from "./Pages/PluginSettings.svelte";
|
||||||
import FilesSettings from "./Pages/FilesSettings.svelte";
|
import FilesSettings from "./Pages/FilesSettings.svelte";
|
||||||
import AdvancedSettings from "./Pages/AdvancedSettings.svelte";
|
import AdvancedSettings from "./Pages/AdvancedSettings.svelte";
|
||||||
import { SizeStore, settingsOpen } from "src/ts/stores";
|
import { settingsOpen } from "src/ts/stores";
|
||||||
import Botpreset from "./botpreset.svelte";
|
import Botpreset from "./botpreset.svelte";
|
||||||
import Communities from "./Pages/Communities.svelte";
|
import Communities from "./Pages/Communities.svelte";
|
||||||
import { openURL } from "src/ts/globalApi";
|
import GlobalLoreBookSettings from "./Pages/GlobalLoreBookSettings.svelte";
|
||||||
|
import Lorepreset from "./lorepreset.svelte";
|
||||||
let selected = -1
|
let selected = -1
|
||||||
let openPresetList = false
|
let openPresetList = false
|
||||||
|
let openLoreList = false
|
||||||
if(window.innerWidth >= 700){
|
if(window.innerWidth >= 700){
|
||||||
selected = 0
|
selected = 0
|
||||||
}
|
}
|
||||||
@@ -48,6 +50,12 @@
|
|||||||
<MonitorIcon />
|
<MonitorIcon />
|
||||||
<span>{language.display}</span>
|
<span>{language.display}</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button class="text-gray-400 flex gap-2 items-center hover:text-gray-200" class:text-white={selected === 8} on:click={() => {
|
||||||
|
selected = 8
|
||||||
|
}}>
|
||||||
|
<BookIcon />
|
||||||
|
<span>{language.globalLoreBook}</span>
|
||||||
|
</button>
|
||||||
<button class="text-gray-400 flex gap-2 items-center hover:text-gray-200" class:text-white={selected === 4} on:click={() => {
|
<button class="text-gray-400 flex gap-2 items-center hover:text-gray-200" class:text-white={selected === 4} on:click={() => {
|
||||||
selected = 4
|
selected = 4
|
||||||
}}>
|
}}>
|
||||||
@@ -97,6 +105,8 @@
|
|||||||
<AdvancedSettings />
|
<AdvancedSettings />
|
||||||
{:else if selected === 7}
|
{:else if selected === 7}
|
||||||
<Communities />
|
<Communities />
|
||||||
|
{:else if selected === 8}
|
||||||
|
<GlobalLoreBookSettings bind:openLoreList />
|
||||||
{/if}
|
{/if}
|
||||||
<button class="absolute top-2 right-2 hover:text-green-500" on:click={() => {
|
<button class="absolute top-2 right-2 hover:text-green-500" on:click={() => {
|
||||||
if(window.innerWidth >= 700){
|
if(window.innerWidth >= 700){
|
||||||
@@ -115,6 +125,9 @@
|
|||||||
{#if openPresetList}
|
{#if openPresetList}
|
||||||
<Botpreset close={() => {openPresetList = false}} />
|
<Botpreset close={() => {openPresetList = false}} />
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if openLoreList}
|
||||||
|
<Lorepreset close={() => {openLoreList = false}} />
|
||||||
|
{/if}
|
||||||
<style>
|
<style>
|
||||||
.setting-bg{
|
.setting-bg{
|
||||||
background: linear-gradient(to right, #21222C 50%, #282a36 50%);
|
background: linear-gradient(to right, #21222C 50%, #282a36 50%);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<script>
|
<script>
|
||||||
import { alertConfirm, alertError } from "../../ts/alert";
|
import { alertConfirm, alertError } from "../../ts/alert";
|
||||||
import { language } from "../../lang";
|
import { language } from "../../lang";
|
||||||
import { DataBase, changeToPreset, presetTemplate } from "../../ts/database";
|
import { DataBase, changeToPreset, copyPreset, presetTemplate } from "../../ts/database";
|
||||||
import { EditIcon, PlusIcon, TrashIcon, XIcon } from "lucide-svelte";
|
import { CopyIcon, EditIcon, PlusIcon, TrashIcon, XIcon } from "lucide-svelte";
|
||||||
|
|
||||||
let editMode = false
|
let editMode = false
|
||||||
export let close = () => {}
|
export let close = () => {}
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="absolute w-full h-full z-40 bg-black bg-opacity-50 flex justify-center items-center">
|
<div class="absolute w-full h-full z-40 bg-black bg-opacity-50 flex justify-center items-center">
|
||||||
<div class="bg-darkbg p-4 break-any rounded-md flex flex-col max-w-3xl w-96">
|
<div class="bg-darkbg p-4 break-any rounded-md flex flex-col max-w-3xl w-96 max-h-full overflow-y-auto">
|
||||||
<div class="flex items-center text-neutral-200 mb-4">
|
<div class="flex items-center text-neutral-200 mb-4">
|
||||||
<h2 class="mt-0 mb-0">{language.presets}</h2>
|
<h2 class="mt-0 mb-0">{language.presets}</h2>
|
||||||
<div class="flex-grow flex justify-end">
|
<div class="flex-grow flex justify-end">
|
||||||
@@ -35,6 +35,12 @@
|
|||||||
<span>{presets.name}</span>
|
<span>{presets.name}</span>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="flex-grow flex justify-end">
|
<div class="flex-grow flex justify-end">
|
||||||
|
<button class="text-gray-500 hover:text-green-500 cursor-pointer mr-2" on:click={(e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
copyPreset(i)
|
||||||
|
}}>
|
||||||
|
<CopyIcon size={18}/>
|
||||||
|
</button>
|
||||||
<button class="text-gray-500 hover:text-green-500 cursor-pointer" on:click={async (e) => {
|
<button class="text-gray-500 hover:text-green-500 cursor-pointer" on:click={async (e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
if($DataBase.botPresets.length === 1){
|
if($DataBase.botPresets.length === 1){
|
||||||
|
|||||||
77
src/lib/Setting/lorepreset.svelte
Normal file
77
src/lib/Setting/lorepreset.svelte
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<script>
|
||||||
|
import { alertConfirm, alertError } from "../../ts/alert";
|
||||||
|
import { language } from "../../lang";
|
||||||
|
import { DataBase } from "../../ts/database";
|
||||||
|
import { EditIcon, PlusIcon, TrashIcon, XIcon } from "lucide-svelte";
|
||||||
|
let editMode = false
|
||||||
|
export let close = () => {}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="absolute w-full h-full z-40 bg-black bg-opacity-50 flex justify-center items-center">
|
||||||
|
<div class="bg-darkbg p-4 break-any rounded-md flex flex-col max-w-3xl w-96 max-h-full overflow-y-auto">
|
||||||
|
<div class="flex items-center text-neutral-200 mb-4">
|
||||||
|
<h2 class="mt-0 mb-0">{language.loreBook}</h2>
|
||||||
|
<div class="flex-grow flex justify-end">
|
||||||
|
<button class="text-gray-500 hover:text-green-500 mr-2 cursor-pointer items-center" on:click={close}>
|
||||||
|
<XIcon size={24}/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{#each $DataBase.loreBook as lore, ind}
|
||||||
|
<button on:click={() => {
|
||||||
|
if(!editMode){
|
||||||
|
$DataBase.loreBookPage = ind
|
||||||
|
}
|
||||||
|
}} class="flex items-center text-neutral-200 border-t-1 border-solid border-0 border-gray-600 p-2 cursor-pointer" class:bg-selected={ind === $DataBase.loreBookPage}>
|
||||||
|
{#if editMode}
|
||||||
|
<input class="text-neutral-200 p-2 bg-transparent input-text focus:bg-selected" bind:value={$DataBase.loreBook[ind].name} placeholder="string">
|
||||||
|
{:else}
|
||||||
|
<span>{lore.name}</span>
|
||||||
|
{/if}
|
||||||
|
<div class="flex-grow flex justify-end">
|
||||||
|
<button class="text-gray-500 hover:text-green-500 cursor-pointer" on:click={async (e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
if($DataBase.loreBook.length === 1){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const d = await alertConfirm(`${language.removeConfirm}${lore.name}`)
|
||||||
|
if(d){
|
||||||
|
$DataBase.loreBookPage = 0
|
||||||
|
let loreBook = $DataBase.loreBook
|
||||||
|
loreBook.splice(ind, 1)
|
||||||
|
$DataBase.loreBook = loreBook
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<TrashIcon size={18}/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
{/each}
|
||||||
|
<div class="flex mt-2 items-center">
|
||||||
|
<button class="text-gray-500 hover:text-green-500 cursor-pointer mr-1" on:click={() => {
|
||||||
|
let loreBooks = $DataBase.loreBook
|
||||||
|
let newLoreBook = {
|
||||||
|
name: `New LoreBook`,
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
loreBooks.push(newLoreBook)
|
||||||
|
|
||||||
|
$DataBase.loreBook = loreBooks
|
||||||
|
}}>
|
||||||
|
<PlusIcon/>
|
||||||
|
</button>
|
||||||
|
<button class="text-gray-500 hover:text-green-500 cursor-pointer" on:click={() => {
|
||||||
|
editMode = !editMode
|
||||||
|
}}>
|
||||||
|
<EditIcon size={18}/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.break-any{
|
||||||
|
word-break: normal;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -181,9 +181,9 @@
|
|||||||
<span class="text-neutral-200">{language.firstMessage} <Help key="charFirstMessage"/></span>
|
<span class="text-neutral-200">{language.firstMessage} <Help key="charFirstMessage"/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.firstMessage}></textarea>
|
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.firstMessage}></textarea>
|
||||||
<span class="text-gray-400 mb-6 text-sm">{tokens.firstMsg} {language.tokens}</span>
|
<span class="text-gray-400 mb-6 text-sm">{tokens.firstMsg} {language.tokens}</span>
|
||||||
<span class="text-neutral-200">{language.authorNote} <Help key="charNote"/></span>
|
<span class="text-neutral-200">{language.authorNote} <Help key="chatNote"/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 resize-none h-20 focus:bg-selected text-xs" autocomplete="off" bind:value={currentChar.data.postHistoryInstructions}></textarea>
|
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 resize-none h-20 focus:bg-selected text-xs" autocomplete="off" bind:value={currentChar.data.chats[currentChar.data.chatPage].note}></textarea>
|
||||||
<span class="text-gray-400 mb-6 text-sm">{tokens.charaNote} {language.tokens}</span>
|
<span class="text-gray-400 mb-6 text-sm">{tokens.localNote} {language.tokens}</span>
|
||||||
|
|
||||||
{:else}
|
{:else}
|
||||||
<input class="text-neutral-200 mt-2 mb-4 p-2 bg-transparent input-text text-xl focus:bg-selected" placeholder="Group Name" bind:value={currentChar.data.name}>
|
<input class="text-neutral-200 mt-2 mb-4 p-2 bg-transparent input-text text-xl focus:bg-selected" placeholder="Group Name" bind:value={currentChar.data.name}>
|
||||||
@@ -213,11 +213,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="text-neutral-200">{language.chatNotes} <Help key="charNote"/></span>
|
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 resize-none h-20 focus:bg-selected text-xs" autocomplete="off" bind:value={currentChar.data.chats[currentChar.data.chatPage].note}></textarea>
|
|
||||||
<span class="text-gray-400 mb-6 text-sm">{tokens.localNote} {language.tokens}</span>
|
|
||||||
|
|
||||||
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="flex mt-6 items-center">
|
<div class="flex mt-6 items-center">
|
||||||
@@ -520,9 +515,9 @@
|
|||||||
<span class="text-neutral-200">{language.systemPrompt} <Help key="systemPrompt"/></span>
|
<span class="text-neutral-200">{language.systemPrompt} <Help key="systemPrompt"/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.systemPrompt}></textarea>
|
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.systemPrompt}></textarea>
|
||||||
|
|
||||||
<span class="text-neutral-200">{language.chatNotes} <Help key="chatNote"/></span>
|
<span class="text-neutral-200">{language.replaceGlobalNote} <Help key="replaceGlobalNote"/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 resize-none h-20 focus:bg-selected text-xs" autocomplete="off" bind:value={currentChar.data.chats[currentChar.data.chatPage].note}></textarea>
|
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.replaceGlobalNote}></textarea>
|
||||||
<span class="text-gray-400 mb-6 text-sm">{tokens.localNote} {language.tokens}</span>
|
|
||||||
|
|
||||||
{#if currentChar.data.chats[currentChar.data.chatPage].supaMemoryData && currentChar.data.chats[currentChar.data.chatPage].supaMemoryData.length > 4}
|
{#if currentChar.data.chats[currentChar.data.chatPage].supaMemoryData && currentChar.data.chats[currentChar.data.chatPage].supaMemoryData.length > 4}
|
||||||
<span class="text-neutral-200">{language.SuperMemory}</span>
|
<span class="text-neutral-200">{language.SuperMemory}</span>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
import LoreBookData from "./LoreBookData.svelte";
|
import LoreBookData from "./LoreBookData.svelte";
|
||||||
import Check from "../Others/Check.svelte";
|
import Check from "../Others/Check.svelte";
|
||||||
let submenu = 0
|
let submenu = 0
|
||||||
let globalMode = false
|
export let globalMode = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if !globalMode}
|
{#if !globalMode}
|
||||||
@@ -30,9 +30,26 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if submenu !== 2}
|
{#if submenu !== 2}
|
||||||
|
{#if !globalMode}
|
||||||
<span class="text-gray-500 mt-2 mb-6 text-sm">{submenu === 0 ? $DataBase.characters[$selectedCharID].type === 'group' ? language.groupLoreInfo : language.globalLoreInfo : language.localLoreInfo}</span>
|
<span class="text-gray-500 mt-2 mb-6 text-sm">{submenu === 0 ? $DataBase.characters[$selectedCharID].type === 'group' ? language.groupLoreInfo : language.globalLoreInfo : language.localLoreInfo}</span>
|
||||||
|
{/if}
|
||||||
<div class="border-solid border-borderc p-2 flex flex-col border-1">
|
<div class="border-solid border-borderc p-2 flex flex-col border-1">
|
||||||
{#if submenu === 0}
|
{#if globalMode}
|
||||||
|
{#if $DataBase.loreBook[$DataBase.loreBookPage].data.length === 0}
|
||||||
|
<span class="text-gray-500">No Lorebook</span>
|
||||||
|
{:else}
|
||||||
|
{#each $DataBase.loreBook[$DataBase.loreBookPage].data as book, i}
|
||||||
|
{#if i !== 0}
|
||||||
|
<div class="border-borderc mt-2 mb-2 w-full border-solid border-b-1 seperator"></div>
|
||||||
|
{/if}
|
||||||
|
<LoreBookData bind:value={$DataBase.loreBook[$DataBase.loreBookPage].data[i]} onRemove={() => {
|
||||||
|
let lore = $DataBase.loreBook[$DataBase.loreBookPage].data
|
||||||
|
lore.splice(i, 1)
|
||||||
|
$DataBase.loreBook[$DataBase.loreBookPage].data = lore
|
||||||
|
}}/>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
{:else if submenu === 0}
|
||||||
{#if $DataBase.characters[$selectedCharID].globalLore.length === 0}
|
{#if $DataBase.characters[$selectedCharID].globalLore.length === 0}
|
||||||
<span class="text-gray-500">No Lorebook</span>
|
<span class="text-gray-500">No Lorebook</span>
|
||||||
{:else}
|
{:else}
|
||||||
@@ -96,16 +113,16 @@
|
|||||||
{#if submenu !== 2}
|
{#if submenu !== 2}
|
||||||
|
|
||||||
<div class="text-gray-500 mt-2 flex">
|
<div class="text-gray-500 mt-2 flex">
|
||||||
<button on:click={() => {addLorebook(submenu)}} class="hover:text-neutral-200 cursor-pointer">
|
<button on:click={() => {addLorebook(globalMode ? -1 : submenu)}} class="hover:text-neutral-200 cursor-pointer">
|
||||||
<PlusIcon />
|
<PlusIcon />
|
||||||
</button>
|
</button>
|
||||||
<button on:click={() => {
|
<button on:click={() => {
|
||||||
exportLoreBook(submenu === 0 ? 'global' : 'local')
|
exportLoreBook(globalMode ? 'sglobal' : submenu === 0 ? 'global' : 'local')
|
||||||
}} class="hover:text-neutral-200 ml-1 cursor-pointer">
|
}} class="hover:text-neutral-200 ml-1 cursor-pointer">
|
||||||
<DownloadIcon />
|
<DownloadIcon />
|
||||||
</button>
|
</button>
|
||||||
<button on:click={() => {
|
<button on:click={() => {
|
||||||
importLoreBook(submenu === 0 ? 'global' : 'local')
|
importLoreBook(globalMode ? 'sglobal' : submenu === 0 ? 'global' : 'local')
|
||||||
}} class="hover:text-neutral-200 ml-2 cursor-pointer">
|
}} class="hover:text-neutral-200 ml-2 cursor-pointer">
|
||||||
<FolderUpIcon />
|
<FolderUpIcon />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -289,16 +289,16 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex h-full w-20 min-w-20 flex-col items-center overflow-x-hidden overflow-y-scroll bg-bgcolor text-white shadow-lg"
|
class="flex h-full w-20 min-w-20 flex-col items-center bg-bgcolor text-white shadow-lg"
|
||||||
class:editMode
|
class:editMode
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="absolute top-0 flex h-8 w-14 min-w-14 cursor-pointer items-center justify-center rounded-b-md bg-gray-500 transition-colors hover:bg-green-500"
|
class="flex h-8 w-14 min-w-14 cursor-pointer items-center justify-center rounded-b-md bg-gray-500 transition-colors hover:bg-green-500"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
menuMode = 1 - menuMode;
|
menuMode = 1 - menuMode;
|
||||||
}}><ListIcon /></button
|
}}><ListIcon />
|
||||||
>
|
</button>
|
||||||
<div class="h-8 min-h-8 w-14 min-w-14 bg-transparent" />
|
<div class="flex flex-grow w-full flex-col items-center overflow-x-hidden overflow-y-auto pr-0">
|
||||||
<div class="h-4 min-h-4 w-14" on:dragover={(e) => {
|
<div class="h-4 min-h-4 w-14" on:dragover={(e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.dataTransfer.dropEffect = 'move'
|
e.dataTransfer.dropEffect = 'move'
|
||||||
@@ -480,6 +480,7 @@
|
|||||||
}
|
}
|
||||||
}}><Settings /></BarIcon
|
}}><Settings /></BarIcon
|
||||||
>
|
>
|
||||||
|
<div class="mt-2"></div>
|
||||||
<BarIcon
|
<BarIcon
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
reseter();
|
reseter();
|
||||||
@@ -487,6 +488,7 @@
|
|||||||
}}><LayoutGridIcon /></BarIcon
|
}}><LayoutGridIcon /></BarIcon
|
||||||
>
|
>
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="setting-area flex w-96 flex-col overflow-y-auto overflow-x-hidden bg-darkbg p-6 text-gray-200"
|
class="setting-area flex w-96 flex-col overflow-y-auto overflow-x-hidden bg-darkbg p-6 text-gray-200"
|
||||||
|
|||||||
32
src/lib/UI/ModelList.svelte
Normal file
32
src/lib/UI/ModelList.svelte
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { DataBase } from "src/ts/database";
|
||||||
|
import { isTauri } from "src/ts/globalApi";
|
||||||
|
import { getHordeModels } from "src/ts/horde/getModels";
|
||||||
|
|
||||||
|
export let value = ""
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#await getHordeModels()}
|
||||||
|
<select class="bg-transparent input-text mt-2 mb-2 text-gray-200 appearance-none text-sm" value="">
|
||||||
|
<option value="" class="bg-darkbg appearance-none">Loading...</option>
|
||||||
|
</select>
|
||||||
|
{:then models}
|
||||||
|
<select class="bg-transparent input-text mt-2 mb-2 text-gray-200 appearance-none text-sm" bind:value>
|
||||||
|
<optgroup class="bg-darkbg appearance-none" label="OpenAI">
|
||||||
|
<option value="gpt35" class="bg-darkbg appearance-none">OpenAI GPT-3.5</option>
|
||||||
|
<option value="gpt4" class="bg-darkbg appearance-none">OpenAI GPT-4</option>
|
||||||
|
</optgroup>
|
||||||
|
<optgroup class="bg-darkbg appearance-none" label="Other Providers">
|
||||||
|
<option value="palm2" class="bg-darkbg appearance-none">Google Palm2</option>
|
||||||
|
<option value="textgen_webui" class="bg-darkbg appearance-none">Text Generation WebUI</option>
|
||||||
|
{#if $DataBase.plugins.length > 0}
|
||||||
|
<option value="custom" class="bg-darkbg appearance-none">Plugin</option>
|
||||||
|
{/if}
|
||||||
|
</optgroup>
|
||||||
|
<!-- <optgroup class="bg-darkbg appearance-none" label="Horde">
|
||||||
|
{#each models as model}
|
||||||
|
<option value={"horde:::" + model} class="bg-darkbg appearance-none">{model}</option>
|
||||||
|
{/each}
|
||||||
|
</optgroup> -->
|
||||||
|
</select>
|
||||||
|
{/await}
|
||||||
@@ -203,7 +203,8 @@ function convertOldTavernAndJSON(charaData:OldTavernChar, imgp:string|undefined
|
|||||||
characterVersion: 0,
|
characterVersion: 0,
|
||||||
personality: charaData.personality ?? '',
|
personality: charaData.personality ?? '',
|
||||||
scenario:charaData.scenario ?? '',
|
scenario:charaData.scenario ?? '',
|
||||||
firstMsgIndex: -1
|
firstMsgIndex: -1,
|
||||||
|
replaceGlobalNote: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,7 +382,7 @@ async function importSpecv2(card:CharacterCardV2, img?:Uint8Array):Promise<boole
|
|||||||
mode: "normal",
|
mode: "normal",
|
||||||
alwaysActive: book.constant ?? false,
|
alwaysActive: book.constant ?? false,
|
||||||
selective: book.selective ?? false,
|
selective: book.selective ?? false,
|
||||||
extentions: book.extensions
|
extentions: {...book.extensions, risu_case_sensitive: book.case_sensitive}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,7 +413,7 @@ async function importSpecv2(card:CharacterCardV2, img?:Uint8Array):Promise<boole
|
|||||||
exampleMessage: data.mes_example ?? '',
|
exampleMessage: data.mes_example ?? '',
|
||||||
creatorNotes:data.creator_notes ?? '',
|
creatorNotes:data.creator_notes ?? '',
|
||||||
systemPrompt:data.system_prompt ?? '',
|
systemPrompt:data.system_prompt ?? '',
|
||||||
postHistoryInstructions:data.post_history_instructions ?? '',
|
postHistoryInstructions:'',
|
||||||
alternateGreetings:data.alternate_greetings ?? [],
|
alternateGreetings:data.alternate_greetings ?? [],
|
||||||
tags:data.tags ?? [],
|
tags:data.tags ?? [],
|
||||||
creator:data.creator ?? '',
|
creator:data.creator ?? '',
|
||||||
@@ -428,7 +429,8 @@ async function importSpecv2(card:CharacterCardV2, img?:Uint8Array):Promise<boole
|
|||||||
creator: data.creator,
|
creator: data.creator,
|
||||||
character_version: data.character_version
|
character_version: data.character_version
|
||||||
},
|
},
|
||||||
additionalAssets: extAssets
|
additionalAssets: extAssets,
|
||||||
|
replaceGlobalNote: data.post_history_instructions ?? ''
|
||||||
}
|
}
|
||||||
|
|
||||||
db.characters.push(char)
|
db.characters.push(char)
|
||||||
@@ -458,7 +460,8 @@ export async function exportSpecV2(char:character) {
|
|||||||
constant: lore.alwaysActive,
|
constant: lore.alwaysActive,
|
||||||
selective:lore.selective,
|
selective:lore.selective,
|
||||||
name: lore.comment,
|
name: lore.comment,
|
||||||
comment: lore.comment
|
comment: lore.comment,
|
||||||
|
case_sensitive: lore.extentions?.risu_case_sensitive
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,7 +477,7 @@ export async function exportSpecV2(char:character) {
|
|||||||
mes_example: char.exampleMessage,
|
mes_example: char.exampleMessage,
|
||||||
creator_notes: char.creatorNotes,
|
creator_notes: char.creatorNotes,
|
||||||
system_prompt: char.systemPrompt,
|
system_prompt: char.systemPrompt,
|
||||||
post_history_instructions: char.postHistoryInstructions,
|
post_history_instructions: char.replaceGlobalNote,
|
||||||
alternate_greetings: char.alternateGreetings,
|
alternate_greetings: char.alternateGreetings,
|
||||||
character_book: {
|
character_book: {
|
||||||
scan_depth: char.loreSettings?.scanDepth,
|
scan_depth: char.loreSettings?.scanDepth,
|
||||||
@@ -625,5 +628,5 @@ interface charBookEntry{
|
|||||||
secondary_keys?: Array<string> // see field `selective`. ignored if selective == false
|
secondary_keys?: Array<string> // see field `selective`. ignored if selective == false
|
||||||
constant?: boolean // if true, always inserted in the prompt (within budget limit)
|
constant?: boolean // if true, always inserted in the prompt (within budget limit)
|
||||||
position?: 'before_char' | 'after_char' // whether the entry is placed before or after the character defs
|
position?: 'before_char' | 'after_char' // whether the entry is placed before or after the character defs
|
||||||
|
case_sensitive?:boolean
|
||||||
}
|
}
|
||||||
@@ -275,7 +275,6 @@ export function characterFormatUpdate(index:number|character){
|
|||||||
cha.exampleMessage = cha.exampleMessage ?? ''
|
cha.exampleMessage = cha.exampleMessage ?? ''
|
||||||
cha.creatorNotes = cha.creatorNotes ?? ''
|
cha.creatorNotes = cha.creatorNotes ?? ''
|
||||||
cha.systemPrompt = cha.systemPrompt ?? ''
|
cha.systemPrompt = cha.systemPrompt ?? ''
|
||||||
cha.postHistoryInstructions = cha.postHistoryInstructions ?? ''
|
|
||||||
cha.tags = cha.tags ?? []
|
cha.tags = cha.tags ?? []
|
||||||
cha.creator = cha.creator ?? ''
|
cha.creator = cha.creator ?? ''
|
||||||
cha.characterVersion = cha.characterVersion ?? 0
|
cha.characterVersion = cha.characterVersion ?? 0
|
||||||
@@ -288,6 +287,12 @@ export function characterFormatUpdate(index:number|character){
|
|||||||
character_version: 0
|
character_version: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(cha.postHistoryInstructions){
|
||||||
|
cha.chats[cha.chatPage].note += "\n" + cha.postHistoryInstructions
|
||||||
|
cha.chats[cha.chatPage].note = cha.chats[cha.chatPage].note.trim()
|
||||||
|
cha.postHistoryInstructions = null
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if(checkNullish(cha.customscript)){
|
if(checkNullish(cha.customscript)){
|
||||||
cha.customscript = []
|
cha.customscript = []
|
||||||
@@ -332,7 +337,8 @@ export function createBlankChar():character{
|
|||||||
characterVersion: 0,
|
characterVersion: 0,
|
||||||
personality:"",
|
personality:"",
|
||||||
scenario:"",
|
scenario:"",
|
||||||
firstMsgIndex: -1
|
firstMsgIndex: -1,
|
||||||
|
replaceGlobalNote: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { cloneDeep } from 'lodash';
|
|||||||
|
|
||||||
export const DataBase = writable({} as any as Database)
|
export const DataBase = writable({} as any as Database)
|
||||||
export const loadedStore = writable(false)
|
export const loadedStore = writable(false)
|
||||||
export let appVer = '1.15.6'
|
export let appVer = '1.16.0'
|
||||||
|
|
||||||
|
|
||||||
export function setDatabase(data:Database){
|
export function setDatabase(data:Database){
|
||||||
@@ -222,6 +222,26 @@ export function setDatabase(data:Database){
|
|||||||
FontColorItalicBold: "#8C8D93"
|
FontColorItalicBold: "#8C8D93"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(checkNullish(data.hordeConfig)){
|
||||||
|
data.hordeConfig = {
|
||||||
|
apiKey: "",
|
||||||
|
model: "",
|
||||||
|
softPrompt: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(checkNullish(data.novelai)){
|
||||||
|
data.novelai = {
|
||||||
|
token: "",
|
||||||
|
model: "clio-v1",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(checkNullish(data.loreBook)){
|
||||||
|
data.loreBookPage = 0
|
||||||
|
data.loreBook = [{
|
||||||
|
name: "My First LoreBook",
|
||||||
|
data: []
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
changeLanguage(data.language)
|
changeLanguage(data.language)
|
||||||
@@ -246,7 +266,9 @@ export interface loreBook{
|
|||||||
mode: 'multiple'|'constant'|'normal',
|
mode: 'multiple'|'constant'|'normal',
|
||||||
alwaysActive: boolean
|
alwaysActive: boolean
|
||||||
selective:boolean
|
selective:boolean
|
||||||
extentions?:{}
|
extentions?:{
|
||||||
|
risu_case_sensitive:boolean
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface character{
|
export interface character{
|
||||||
@@ -290,6 +312,7 @@ export interface character{
|
|||||||
supaMemory?:boolean
|
supaMemory?:boolean
|
||||||
additionalAssets?:[string, string][]
|
additionalAssets?:[string, string][]
|
||||||
ttsReadOnlyQuoted?:boolean
|
ttsReadOnlyQuoted?:boolean
|
||||||
|
replaceGlobalNote:string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -366,6 +389,11 @@ export interface Database{
|
|||||||
jailbreakToggle:boolean
|
jailbreakToggle:boolean
|
||||||
loreBookDepth: number
|
loreBookDepth: number
|
||||||
loreBookToken: number,
|
loreBookToken: number,
|
||||||
|
loreBook: {
|
||||||
|
name:string
|
||||||
|
data:loreBook[]
|
||||||
|
}[]
|
||||||
|
loreBookPage: number
|
||||||
supaMemoryPrompt: string
|
supaMemoryPrompt: string
|
||||||
username: string
|
username: string
|
||||||
userIcon: string
|
userIcon: string
|
||||||
@@ -431,6 +459,17 @@ export interface Database{
|
|||||||
textScreenRounded?:boolean
|
textScreenRounded?:boolean
|
||||||
textScreenBorder?:string
|
textScreenBorder?:string
|
||||||
characterOrder:(string|folder)[]
|
characterOrder:(string|folder)[]
|
||||||
|
hordeConfig:hordeConfig,
|
||||||
|
novelai:{
|
||||||
|
token:string,
|
||||||
|
model:string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface hordeConfig{
|
||||||
|
apiKey:string
|
||||||
|
model:string
|
||||||
|
softPrompt:string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface folder{
|
export interface folder{
|
||||||
@@ -542,7 +581,7 @@ export function updateTextTheme(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function changeToPreset(id =0){
|
export function saveCurrentPreset(){
|
||||||
let db = get(DataBase)
|
let db = get(DataBase)
|
||||||
let pres = db.botPresets
|
let pres = db.botPresets
|
||||||
pres[db.botPresetsId] = {
|
pres[db.botPresetsId] = {
|
||||||
@@ -568,6 +607,23 @@ export function changeToPreset(id =0){
|
|||||||
bias: db.bias
|
bias: db.bias
|
||||||
}
|
}
|
||||||
db.botPresets = pres
|
db.botPresets = pres
|
||||||
|
DataBase.set(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function copyPreset(id:number){
|
||||||
|
saveCurrentPreset()
|
||||||
|
let db = get(DataBase)
|
||||||
|
let pres = db.botPresets
|
||||||
|
const newPres = cloneDeep(pres[id])
|
||||||
|
newPres.name += " Copy"
|
||||||
|
db.botPresets.push(newPres)
|
||||||
|
DataBase.set(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function changeToPreset(id =0){
|
||||||
|
saveCurrentPreset()
|
||||||
|
let db = get(DataBase)
|
||||||
|
let pres = db.botPresets
|
||||||
const newPres = pres[id]
|
const newPres = pres[id]
|
||||||
db.botPresetsId = id
|
db.botPresetsId = id
|
||||||
db.apiType = newPres.apiType ?? db.apiType
|
db.apiType = newPres.apiType ?? db.apiType
|
||||||
|
|||||||
34
src/ts/horde/getModels.ts
Normal file
34
src/ts/horde/getModels.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { sleep } from "../util"
|
||||||
|
|
||||||
|
let modelList:string[]|'loading' = null
|
||||||
|
|
||||||
|
//until horde is ready
|
||||||
|
modelList = []
|
||||||
|
|
||||||
|
export async function getHordeModels():Promise<string[]> {
|
||||||
|
|
||||||
|
if(modelList === null){
|
||||||
|
try {
|
||||||
|
modelList = 'loading'
|
||||||
|
const models = await fetch("https://stablehorde.net/api/v2/status/models?type=text")
|
||||||
|
modelList = ((await models.json()).map((a) => {
|
||||||
|
return a.name
|
||||||
|
}) as string[])
|
||||||
|
return modelList
|
||||||
|
} catch (error) {
|
||||||
|
modelList = null
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(modelList === 'loading'){
|
||||||
|
while(true){
|
||||||
|
if(modelList !== 'loading'){
|
||||||
|
return getHordeModels()
|
||||||
|
}
|
||||||
|
await sleep(10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return modelList
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ export interface OpenAIChat{
|
|||||||
role: 'system'|'user'|'assistant'
|
role: 'system'|'user'|'assistant'
|
||||||
content: string
|
content: string
|
||||||
memo?:string
|
memo?:string
|
||||||
|
name?:string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const doingChat = writable(false)
|
export const doingChat = writable(false)
|
||||||
@@ -104,7 +105,7 @@ export async function sendChat(chatProcessIndex = -1):Promise<boolean> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!currentChar.utilityBot){
|
if(!currentChar.utilityBot){
|
||||||
const mainp = currentChar.systemPrompt.length > 3 ? currentChar.systemPrompt : db.mainPrompt
|
const mainp = currentChar.systemPrompt || db.mainPrompt
|
||||||
|
|
||||||
unformated.main.push({
|
unformated.main.push({
|
||||||
role: 'system',
|
role: 'system',
|
||||||
@@ -120,14 +121,14 @@ export async function sendChat(chatProcessIndex = -1):Promise<boolean> {
|
|||||||
|
|
||||||
unformated.globalNote.push({
|
unformated.globalNote.push({
|
||||||
role: 'system',
|
role: 'system',
|
||||||
content: replacePlaceholders(db.globalNote, currentChar.name)
|
content: replacePlaceholders(currentChar.replaceGlobalNote || db.globalNote, currentChar.name)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if(currentChat.note !== ''){
|
if(currentChat.note !== ''){
|
||||||
unformated.authorNote.push({
|
unformated.authorNote.push({
|
||||||
role: 'system',
|
role: 'system',
|
||||||
content: replacePlaceholders(currentChar.postHistoryInstructions, currentChat.note)
|
content: replacePlaceholders(currentChat.note, currentChar.name)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,14 +201,17 @@ export async function sendChat(chatProcessIndex = -1):Promise<boolean> {
|
|||||||
const ms = currentChat.message
|
const ms = currentChat.message
|
||||||
for(const msg of ms){
|
for(const msg of ms){
|
||||||
let formedChat = processScript(currentChar,replacePlaceholders(msg.data, currentChar.name), 'editprocess')
|
let formedChat = processScript(currentChar,replacePlaceholders(msg.data, currentChar.name), 'editprocess')
|
||||||
if(nowChatroom.type === 'group'){
|
let name = ''
|
||||||
if(msg.saying && msg.role === 'char'){
|
if(msg.role === 'char'){
|
||||||
formedChat = `${findCharacterbyIdwithCache(msg.saying).name}: ${formedChat}`
|
if(msg.saying){
|
||||||
|
name = `${findCharacterbyIdwithCache(msg.saying).name}`
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
name = `${currentChar.name}`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(msg.role === 'user'){
|
else if(msg.role === 'user'){
|
||||||
formedChat = `${db.username}: ${formedChat}`
|
name = `${db.username}`
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(!msg.chatId){
|
if(!msg.chatId){
|
||||||
msg.chatId = v4()
|
msg.chatId = v4()
|
||||||
@@ -215,7 +219,8 @@ export async function sendChat(chatProcessIndex = -1):Promise<boolean> {
|
|||||||
chats.push({
|
chats.push({
|
||||||
role: msg.role === 'user' ? 'user' : 'assistant',
|
role: msg.role === 'user' ? 'user' : 'assistant',
|
||||||
content: formedChat,
|
content: formedChat,
|
||||||
memo: msg.chatId
|
memo: msg.chatId,
|
||||||
|
name: name
|
||||||
})
|
})
|
||||||
currentTokens += (await tokenize(formedChat) + 1)
|
currentTokens += (await tokenize(formedChat) + 1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,19 @@ import { downloadFile } from "../globalApi";
|
|||||||
export function addLorebook(type:number) {
|
export function addLorebook(type:number) {
|
||||||
let selectedID = get(selectedCharID)
|
let selectedID = get(selectedCharID)
|
||||||
let db = get(DataBase)
|
let db = get(DataBase)
|
||||||
if(type === 0){
|
if(type === -1){
|
||||||
|
db.loreBook[db.loreBookPage].data.push({
|
||||||
|
key: '',
|
||||||
|
comment: `New Lore ${db.loreBook[db.loreBookPage].data.length + 1}`,
|
||||||
|
content: '',
|
||||||
|
mode: 'normal',
|
||||||
|
insertorder: 100,
|
||||||
|
alwaysActive: false,
|
||||||
|
secondkey: "",
|
||||||
|
selective: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if(type === 0){
|
||||||
db.characters[selectedID].globalLore.push({
|
db.characters[selectedID].globalLore.push({
|
||||||
key: '',
|
key: '',
|
||||||
comment: `New Lore ${db.characters[selectedID].globalLore.length + 1}`,
|
comment: `New Lore ${db.characters[selectedID].globalLore.length + 1}`,
|
||||||
@@ -53,9 +65,10 @@ export async function loadLoreBookPrompt(){
|
|||||||
const db = get(DataBase)
|
const db = get(DataBase)
|
||||||
const char = db.characters[selectedID]
|
const char = db.characters[selectedID]
|
||||||
const page = char.chatPage
|
const page = char.chatPage
|
||||||
const globalLore = char.globalLore
|
const characterLore = char.globalLore
|
||||||
const charLore = char.chats[page].localLore
|
const chatLore = char.chats[page].localLore
|
||||||
const fullLore = globalLore.concat(charLore)
|
const globalLore = db.loreBook[db.loreBookPage].data
|
||||||
|
const fullLore = characterLore.concat(chatLore.concat(globalLore))
|
||||||
const currentChat = char.chats[page].message
|
const currentChat = char.chats[page].message
|
||||||
const loreDepth = char.loreSettings?.scanDepth ?? db.loreBookDepth
|
const loreDepth = char.loreSettings?.scanDepth ?? db.loreBookDepth
|
||||||
const loreToken = char.loreSettings?.tokenBudget ?? db.loreBookToken
|
const loreToken = char.loreSettings?.tokenBudget ?? db.loreBookToken
|
||||||
@@ -144,11 +157,14 @@ export async function loadLoreBookPrompt(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function importLoreBook(mode:'global'|'local'){
|
export async function importLoreBook(mode:'global'|'local'|'sglobal'){
|
||||||
const selectedID = get(selectedCharID)
|
const selectedID = get(selectedCharID)
|
||||||
let db = get(DataBase)
|
let db = get(DataBase)
|
||||||
const page = db.characters[selectedID].chatPage
|
const page = db.characters[selectedID].chatPage
|
||||||
let lore = mode === 'global' ? db.characters[selectedID].globalLore : db.characters[selectedID].chats[page].localLore
|
let lore =
|
||||||
|
mode === 'global' ? db.characters[selectedID].globalLore :
|
||||||
|
mode === 'sglobal' ? db.loreBook[db.loreBookPage].data :
|
||||||
|
db.characters[selectedID].chats[page].localLore
|
||||||
const lorebook = (await selectSingleFile(['json'])).data
|
const lorebook = (await selectSingleFile(['json'])).data
|
||||||
if(!lorebook){
|
if(!lorebook){
|
||||||
return
|
return
|
||||||
@@ -189,6 +205,9 @@ export async function importLoreBook(mode:'global'|'local'){
|
|||||||
if(mode === 'global'){
|
if(mode === 'global'){
|
||||||
db.characters[selectedID].globalLore = lore
|
db.characters[selectedID].globalLore = lore
|
||||||
}
|
}
|
||||||
|
if(mode === 'sglobal'){
|
||||||
|
db.loreBook[db.loreBookPage].data = lore
|
||||||
|
}
|
||||||
else{
|
else{
|
||||||
db.characters[selectedID].chats[page].localLore = lore
|
db.characters[selectedID].chats[page].localLore = lore
|
||||||
}
|
}
|
||||||
@@ -198,13 +217,15 @@ export async function importLoreBook(mode:'global'|'local'){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function exportLoreBook(mode:'global'|'local'){
|
export async function exportLoreBook(mode:'global'|'local'|'sglobal'){
|
||||||
try {
|
try {
|
||||||
const selectedID = get(selectedCharID)
|
const selectedID = get(selectedCharID)
|
||||||
const db = get(DataBase)
|
const db = get(DataBase)
|
||||||
const page = db.characters[selectedID].chatPage
|
const page = db.characters[selectedID].chatPage
|
||||||
const lore = mode === 'global' ? db.characters[selectedID].globalLore : db.characters[selectedID].chats[page].localLore
|
const lore =
|
||||||
|
mode === 'global' ? db.characters[selectedID].globalLore :
|
||||||
|
mode === 'sglobal' ? db.loreBook[db.loreBookPage].data :
|
||||||
|
db.characters[selectedID].chats[page].localLore
|
||||||
const stringl = Buffer.from(JSON.stringify({
|
const stringl = Buffer.from(JSON.stringify({
|
||||||
type: 'risu',
|
type: 'risu',
|
||||||
ver: 1,
|
ver: 1,
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ import type { OpenAIChat } from ".";
|
|||||||
import { DataBase, setDatabase, type character } from "../database";
|
import { DataBase, setDatabase, type character } from "../database";
|
||||||
import { pluginProcess } from "./plugins";
|
import { pluginProcess } from "./plugins";
|
||||||
import { language } from "../../lang";
|
import { language } from "../../lang";
|
||||||
import { stringlizeChat } from "./stringlize";
|
import { stringlizeChat, unstringlizeChat } from "./stringlize";
|
||||||
import { globalFetch } from "../globalApi";
|
import { globalFetch, isTauri } from "../globalApi";
|
||||||
|
import { alertError } from "../alert";
|
||||||
|
import { sleep } from "../util";
|
||||||
|
|
||||||
interface requestDataArgument{
|
interface requestDataArgument{
|
||||||
formated: OpenAIChat[]
|
formated: OpenAIChat[]
|
||||||
@@ -34,7 +36,7 @@ export async function requestChatData(arg:requestDataArgument, model:'model'|'su
|
|||||||
return da
|
return da
|
||||||
}
|
}
|
||||||
trys += 1
|
trys += 1
|
||||||
if(trys > db.requestRetrys){
|
if(trys > db.requestRetrys || model.startsWith('horde')){
|
||||||
return da
|
return da
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,6 +55,11 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model'
|
|||||||
switch(aiModel){
|
switch(aiModel){
|
||||||
case 'gpt35':
|
case 'gpt35':
|
||||||
case 'gpt4':{
|
case 'gpt4':{
|
||||||
|
|
||||||
|
for(let i=0;i<formated.length;i++){
|
||||||
|
formated[i].name = undefined
|
||||||
|
}
|
||||||
|
|
||||||
const body = ({
|
const body = ({
|
||||||
model: aiModel === 'gpt35' ? 'gpt-3.5-turbo' : 'gpt-4',
|
model: aiModel === 'gpt35' ? 'gpt-3.5-turbo' : 'gpt-4',
|
||||||
messages: formated,
|
messages: formated,
|
||||||
@@ -168,6 +175,52 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model'
|
|||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
case 'novelai':{
|
||||||
|
if(!isTauri){
|
||||||
|
return{
|
||||||
|
type: 'fail',
|
||||||
|
result: "NovelAI doesn't work in web version."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const proompt = stringlizeChat(formated, currentChar?.name ?? '')
|
||||||
|
const params = {
|
||||||
|
"input": proompt,
|
||||||
|
"model":db.novelai.model,
|
||||||
|
"parameters":{
|
||||||
|
"use_string":true,
|
||||||
|
"temperature":1.7,
|
||||||
|
"max_length":90,
|
||||||
|
"min_length":1,
|
||||||
|
"tail_free_sampling":0.6602,
|
||||||
|
"repetition_penalty":1.0565,
|
||||||
|
"repetition_penalty_range":340,
|
||||||
|
"repetition_penalty_frequency":0,
|
||||||
|
"repetition_penalty_presence":0,
|
||||||
|
"use_cache":false,
|
||||||
|
"return_full_text":false,
|
||||||
|
"prefix":"vanilla",
|
||||||
|
"order":[3,0]}
|
||||||
|
}
|
||||||
|
|
||||||
|
const da = await globalFetch("https://api.novelai.net/ai/generate", {
|
||||||
|
body: params,
|
||||||
|
headers: {
|
||||||
|
"Authorization": "Bearer " + db.novelai.token
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if((!da.ok )|| (!da.data.output)){
|
||||||
|
return {
|
||||||
|
type: 'fail',
|
||||||
|
result: (language.errors.httpError + `${JSON.stringify(da.data)}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: "success",
|
||||||
|
result: unstringlizeChat(da.data.output, formated, currentChar?.name ?? '')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case "textgen_webui":{
|
case "textgen_webui":{
|
||||||
let DURL = db.textgenWebUIURL
|
let DURL = db.textgenWebUIURL
|
||||||
let bodyTemplate:any
|
let bodyTemplate:any
|
||||||
@@ -240,15 +293,9 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model'
|
|||||||
try {
|
try {
|
||||||
let result:string = isNewAPI ? dat.results[0].text : dat.data[0].substring(proompt.length)
|
let result:string = isNewAPI ? dat.results[0].text : dat.data[0].substring(proompt.length)
|
||||||
|
|
||||||
for(const stopStr of stopStrings){
|
|
||||||
if(result.endsWith(stopStr)){
|
|
||||||
result.substring(0,result.length - stopStr.length)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: 'success',
|
type: 'success',
|
||||||
result: result
|
result: unstringlizeChat(result, formated, currentChar?.name ?? '')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
@@ -367,6 +414,106 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model'
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:{
|
default:{
|
||||||
|
if(aiModel.startsWith("horde:::")){
|
||||||
|
const realModel = aiModel.split(":::")[1].trim()
|
||||||
|
|
||||||
|
const workers = ((await (await fetch("https://stablehorde.net/api/v2/workers")).json()) as {id:string,models:string[]}[]).filter((a) => {
|
||||||
|
|
||||||
|
if(a && a.models && a.id){
|
||||||
|
console.log(a)
|
||||||
|
return a.models.includes(realModel)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}).map((a) => {
|
||||||
|
return a.id
|
||||||
|
})
|
||||||
|
|
||||||
|
const argument = {
|
||||||
|
"prompt": "string",
|
||||||
|
"params": {
|
||||||
|
"n": 1,
|
||||||
|
"frmtadsnsp": false,
|
||||||
|
"frmtrmblln": false,
|
||||||
|
"frmtrmspch": false,
|
||||||
|
"frmttriminc": false,
|
||||||
|
"max_context_length": 200,
|
||||||
|
"max_length": 20,
|
||||||
|
"rep_pen": 3,
|
||||||
|
"rep_pen_range": 0,
|
||||||
|
"rep_pen_slope": 10,
|
||||||
|
"singleline": false,
|
||||||
|
"temperature": db.temperature / 25,
|
||||||
|
"tfs": 1,
|
||||||
|
"top_a": 1,
|
||||||
|
"top_k": 100,
|
||||||
|
"top_p": 1,
|
||||||
|
"typical": 1,
|
||||||
|
"sampler_order": [
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"trusted_workers": false,
|
||||||
|
"slow_workers": true,
|
||||||
|
"worker_blacklist": false,
|
||||||
|
"dry_run": false
|
||||||
|
}
|
||||||
|
|
||||||
|
const da = await fetch("https://stablehorde.net/api/v2/generate/text/async", {
|
||||||
|
body: JSON.stringify(argument),
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"content-type": "application/json",
|
||||||
|
"apikey": db.hordeConfig.apiKey
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if(da.status !== 202){
|
||||||
|
return {
|
||||||
|
type: "fail",
|
||||||
|
result: await da.text()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const json:{
|
||||||
|
id:string,
|
||||||
|
kudos:number,
|
||||||
|
message:string
|
||||||
|
} = await da.json()
|
||||||
|
|
||||||
|
let warnMessage = ""
|
||||||
|
if(json.message && json.message.startsWith("Warning:")){
|
||||||
|
warnMessage = "with " + json.message
|
||||||
|
}
|
||||||
|
|
||||||
|
while(true){
|
||||||
|
await sleep(1000)
|
||||||
|
const data = await (await fetch("https://stablehorde.net/api/v2/generate/text/status/" + json.id)).json()
|
||||||
|
if(!data.is_possible){
|
||||||
|
fetch("https://stablehorde.net/api/v2/generate/text/status/" + json.id, {
|
||||||
|
method: "DELETE"
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
type: 'fail',
|
||||||
|
result: "Response not possible" + warnMessage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(data.done){
|
||||||
|
const generations:{text:string}[] = data.generations
|
||||||
|
if(generations && generations.length > 0){
|
||||||
|
return {
|
||||||
|
type: "success",
|
||||||
|
result: generations[0].text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: 'fail',
|
||||||
|
result: "No Generations when done"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
type: 'fail',
|
type: 'fail',
|
||||||
result: (language.errors.unknownModel)
|
result: (language.errors.unknownModel)
|
||||||
|
|||||||
@@ -8,14 +8,48 @@ export function stringlizeChat(formated:OpenAIChat[], char:string = ''){
|
|||||||
let resultString:string[] = []
|
let resultString:string[] = []
|
||||||
for(const form of formated){
|
for(const form of formated){
|
||||||
if(form.role === 'system'){
|
if(form.role === 'system'){
|
||||||
resultString.push("'System Note: " + form.content)
|
resultString.push("system note: " + form.content)
|
||||||
}
|
}
|
||||||
else if(form.role === 'user'){
|
else if(form.name){
|
||||||
resultString.push("user: " + form.content)
|
resultString.push(form.name + ": " + form.content)
|
||||||
}
|
}
|
||||||
else if(form.role === 'assistant'){
|
else{
|
||||||
resultString.push("assistant: " + form.content)
|
resultString.push(form.content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return resultString.join('\n\n') + `\n\n${char}:`
|
return resultString.join('\n\n') + `\n\n${char}:`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function unstringlizeChat(text:string, formated:OpenAIChat[], char:string = ''){
|
||||||
|
console.log(text)
|
||||||
|
let minIndex = -1
|
||||||
|
let chunks:string[] = ["system note:"]
|
||||||
|
if(char){
|
||||||
|
chunks.push(`${char}:`)
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const form of formated){
|
||||||
|
if(form.name){
|
||||||
|
const chunk = `${form.name}:`
|
||||||
|
if(!chunks.includes(chunk)){
|
||||||
|
chunks.push(chunk)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const chunk of chunks){
|
||||||
|
const ind = text.indexOf(chunk)
|
||||||
|
if(ind === -1){
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if(minIndex === -1 || minIndex > ind){
|
||||||
|
minIndex = ind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(minIndex !== -1){
|
||||||
|
text = text.substring(0, minIndex).trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
return text
|
||||||
|
}
|
||||||
@@ -1 +1 @@
|
|||||||
{"version":"1.15.6"}
|
{"version":"1.16.0"}
|
||||||
Reference in New Issue
Block a user