diff --git a/src/lang/en.ts b/src/lang/en.ts index 1a82b1d2..cb866e62 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -700,4 +700,7 @@ export const languageEnglish = { namespace: "Namespace", moduleIntergration: "Module Integration", previewInfo: "This preview shows prompt before model-specific processing.", + miscTools: "Misc Tools", + promptConvertion: "Prompt Convertion", + convertionStep1: "Select all file related to the prompt (Context, Instruct and Sampler JSON is supported)", } \ No newline at end of file diff --git a/src/lib/Playground/PlaygroundMenu.svelte b/src/lib/Playground/PlaygroundMenu.svelte index 84f9a699..9359c1fb 100644 --- a/src/lib/Playground/PlaygroundMenu.svelte +++ b/src/lib/Playground/PlaygroundMenu.svelte @@ -10,8 +10,11 @@ import { characterFormatUpdate, createBlankChar } from "src/ts/characters"; import { get } from "svelte/store"; import { DataBase, setDatabase, type character } from "src/ts/storage/database"; - import PlaygroundImageGen from "./PlaygroundImageGen.svelte"; - import PlaygroundParser from "./PlaygroundParser.svelte"; + import PlaygroundImageGen from "./PlaygroundImageGen.svelte"; + import PlaygroundParser from "./PlaygroundParser.svelte"; + import ToolConvertion from "./ToolConvertion.svelte"; + + let easterEggTouch = 0 const playgroundChat = () => { let db = get(DataBase) @@ -81,6 +84,24 @@ }}>

Parser

+ + {:else} {#if $SizeStore.w < 1024} @@ -114,6 +135,9 @@ {#if $PlaygroundStore === 8} {/if} + {#if $PlaygroundStore === 101} + + {/if} {/if} \ No newline at end of file diff --git a/src/lib/Playground/ToolConvertion.svelte b/src/lib/Playground/ToolConvertion.svelte new file mode 100644 index 00000000..58f46d2f --- /dev/null +++ b/src/lib/Playground/ToolConvertion.svelte @@ -0,0 +1,49 @@ + + +

{language.promptConvertion}

+{language.convertionStep1} + +
+ {#each files as file, i} +
+
+ {#if file.type !== 'NOTSUPPORTED'} + {file.type} + {:else} + NOTSUPPORTED + {/if} + {file.name} +
+ +
+ {/each} + +
+ \ No newline at end of file diff --git a/src/ts/process/prompt.ts b/src/ts/process/prompt.ts index 1b5b1aea..7a73a109 100644 --- a/src/ts/process/prompt.ts +++ b/src/ts/process/prompt.ts @@ -1,6 +1,7 @@ import { get } from "svelte/store"; import { tokenizeAccurate } from "../tokenizer"; -import type { Database } from "../storage/database"; +import { DataBase, presetTemplate, setDatabase, type Database } from "../storage/database"; +import { alertError, alertNormal } from "../alert"; export type PromptItem = PromptItemPlain|PromptItemTyped|PromptItemChat|PromptItemAuthorNote; export type PromptType = PromptItem['type']; @@ -64,3 +65,350 @@ export async function tokenizePreset(prompts:PromptItem[], consti:boolean = fals } return total } + +export function detectPromptJSONType(text:string){ + + function notNull(x:T|null):x is T{ + return x !== null && x !== undefined + } + + try { + const parsed = JSON.parse(text) + if(notNull(parsed.chat_completion_source) && Array.isArray(parsed.prompts)&& Array.isArray(parsed.prompt_order)){ + return "STCHAT" + } + else if(notNull(parsed.temp) && notNull(parsed.rep_pen) && notNull(parsed.min_length)){ + return "PARAMETERS" + } + else if(notNull(parsed.story_string) && notNull(parsed.chat_start)){ + return "STCONTEXT" + } + else if(notNull(parsed.input_sequence) && notNull(parsed.output_sequence)){ + return "STINST" + } + } catch (e) {} + return 'NOTSUPPORTED' +} + +const typePriority = [ + 'STINST', + 'PARAMETERS', + 'STCONTEXT', + 'STCHAT', +] + + +type InstData = { + "system_prompt": string, + "input_sequence": string, + "output_sequence": string, + "last_output_sequence": string, + "system_sequence": string, + "stop_sequence": string, + "system_sequence_prefix": string, + "system_sequence_suffix": string, + "first_output_sequence": string, + "output_suffix": string, + "input_suffix": string, + "system_suffix": string, + "user_alignment_message": string, + "system_same_as_user": boolean, + "last_system_sequence": string, + "first_input_sequence": string, + "last_input_sequence": string, + "name": string +} + +export function stChatConvert(pre:any){ + //ST preset + let promptTemplate = [] + + function findPrompt(identifier:number){ + return pre.prompts.find((p:any) => p.identifier === identifier) + } + + for(const prompt of pre?.prompt_order?.[0]?.order){ + if(!prompt?.enabled){ + continue + } + const p = findPrompt(prompt?.identifier ?? '') + if(p){ + switch(p.identifier){ + case 'main':{ + promptTemplate.push({ + type: 'plain', + type2: 'main', + text: p.content ?? "", + role: p.role ?? "system" + }) + break + } + case 'jailbreak': + case 'nsfw':{ + promptTemplate.push({ + type: 'jailbreak', + type2: 'normal', + text: p.content ?? "", + role: p.role ?? "system" + }) + break + } + case 'dialogueExamples': + case 'charPersonality': + case 'scenario':{ + break //ignore + } + case 'chatHistory':{ + promptTemplate.push({ + type: 'chat', + rangeEnd: 'end', + rangeStart: 0 + }) + break + } + case 'worldInfoBefore':{ + promptTemplate.push({ + type: 'lorebook' + }) + break + } + case 'worldInfoAfter':{ + break + } + case 'charDescription':{ + promptTemplate.push({ + type: 'description' + }) + break + } + case 'personaDescription':{ + promptTemplate.push({ + type: 'persona' + }) + break + } + default:{ + console.log(p) + promptTemplate.push({ + type: 'plain', + type2: 'normal', + text: p.content ?? "", + role: p.role ?? "system" + }) + } + } + } + else{ + console.log("Prompt not found", prompt) + + } + } + if(pre?.assistant_prefill){ + promptTemplate.push({ + type: 'postEverything' + }) + promptTemplate.push({ + type: 'plain', + type2: 'main', + text: `{{#if {{prefill_supported}}}}${pre?.assistant_prefill}{{/if}}`, + role: 'bot' + }) + } + + return promptTemplate +} + +export function promptConvertion(files:{ name: string, content: string, type:string }[]){ + let preset = structuredClone(presetTemplate) + let instData = { + "system_prompt": "", + "input_sequence": "", + "output_sequence": "", + "last_output_sequence": "", + "system_sequence": "", + "stop_sequence": "", + "system_sequence_prefix": "", + "system_sequence_suffix": "", + "first_output_sequence": "", + "output_suffix": "", + "input_suffix": "", + "system_suffix": "", + "user_alignment_message": "", + "system_same_as_user": false, + "last_system_sequence": "", + "first_input_sequence": "", + "last_input_sequence": "", + "name": "" + } + let story_string = '' + let chat_start = '' + preset.name = '' + + let type = '' + + files = files.filter(x=>x.type !== 'NOTSUPPORTED').sort((a,b)=>{ + return typePriority.indexOf(a.type) - typePriority.indexOf(b.type) + }) + + + if(files.findIndex(x=>x.type === 'STINST') !== -1){ + type = 'STINST' + } + if(files.findIndex(x=>x.type === 'STCHAT') !== -1){ + if(type !== ''){ + alertError(`Both ${type} and STCHAT are not supported together.`) + return + } + type = 'STCHAT' + } + + let samplers:string[] = [] + const getParam = (setname:keyof(typeof preset), getname:string = '', arg:{ + multiplier?: number + }={}) => { + if(getname === ''){ + getname = setname + } + let multiplier = arg.multiplier ?? 1 + if(samplers.includes(getname)){ + // @ts-ignore + preset[setname] = data[getname] * multiplier + } + else{ + // @ts-ignore + preset[setname] = -1000 + } + } + + for(let i=0;i