[feat] add llm translation

This commit is contained in:
kwaroran
2023-11-28 04:32:27 +09:00
parent 6ae8264f8b
commit 220c2c091b
5 changed files with 91 additions and 5 deletions

View File

@@ -457,4 +457,5 @@ export const languageEnglish = {
imgGenPrompt: "Image Generation Prompt",
imgGenNegatives: "Image Generation Negative Prompt",
imgGenInstructions: "Image Generation Instructions",
translationPrompt: "Translation Prompt",
}

View File

@@ -8,7 +8,7 @@
import { doingChat, sendChat } from "../../ts/process/index";
import { findCharacterbyId, messageForm, sleep } from "../../ts/util";
import { language } from "../../lang";
import { translate } from "../../ts/translator/translator";
import { isExpTranslator, translate } from "../../ts/translator/translator";
import { alertError, alertNormal, alertWait } from "../../ts/alert";
import sendSound from '../../etc/send.mp3'
import {cloneDeep} from 'lodash'
@@ -251,7 +251,33 @@
$: updateInputSizeAll()
function updateInputTransateMessage(reverse: boolean) {
async function updateInputTransateMessage(reverse: boolean) {
if(isExpTranslator()){
if(!reverse){
messageInputTranslate = ''
return
}
if(messageInputTranslate === '') {
messageInput = ''
return
}
const lastMessageInputTranslate = messageInputTranslate
await sleep(1500)
if(lastMessageInputTranslate === messageInputTranslate){
console.log(lastMessageInputTranslate === messageInputTranslate)
console.log(lastMessageInputTranslate, messageInputTranslate)
translate(reverse ? messageInputTranslate : messageInput, reverse).then((translatedMessage) => {
if(translatedMessage){
if(reverse)
messageInput = translatedMessage
else
messageInputTranslate = translatedMessage
}
})
}
return
}
if(reverse && messageInputTranslate === '') {
messageInput = ''
return

View File

@@ -10,6 +10,7 @@
import { downloadFile } from "src/ts/storage/globalApi";
import { languageEnglish } from "src/lang/en";
import TextInput from "src/lib/UI/GUI/TextInput.svelte";
import TextAreaInput from "src/lib/UI/GUI/TextAreaInput.svelte";
let langChanged = false
</script>
<h2 class="mb-2 text-2xl font-bold mt-2">{language.language}</h2>
@@ -56,6 +57,7 @@
<SelectInput className="mt-2 mb-4" bind:value={$DataBase.translatorType}>
<OptionInput value="google" >Google</OptionInput>
<OptionInput value="deepl" >DeepL</OptionInput>
<OptionInput value="llm" >Ax. Model</OptionInput>
</SelectInput>
{#if $DataBase.translatorType === 'deepl'}
@@ -69,6 +71,11 @@
{/if}
{#if $DataBase.translatorType === 'llm'}
<span class="text-textcolor mt-4">{language.translationPrompt}</span>
<TextAreaInput bind:value={$DataBase.translatorPrompt} placeholder={"You are a translator. translate the following html or text into {{slot}}. do not output anything other than the translation."}/>
{/if}
<div class="flex items-center mt-2">
<Check bind:check={$DataBase.autoTranslate} name={language.autoTranslation}/>

View File

@@ -520,7 +520,7 @@ export interface Database{
mancerHeader:string
emotionProcesser:'submodel'|'embedding',
showMenuChatList?:boolean,
translatorType:'google'|'deepl'|'none',
translatorType:'google'|'deepl'|'none'|'llm',
NAIadventure?:boolean,
NAIappendName?:boolean,
deeplOptions:{
@@ -541,6 +541,7 @@ export interface Database{
automark?:boolean
huggingfaceKey:string
allowAllExtentionFiles?:boolean
translatorPrompt:string
}
export interface customscript{

View File

@@ -3,6 +3,8 @@ import { translatorPlugin } from "../plugins/plugins"
import { DataBase } from "../storage/database"
import { globalFetch } from "../storage/globalApi"
import { alertError } from "../alert"
import { requestChatData } from "../process/request"
import { doingChat } from "../process"
let cache={
origin: [''],
@@ -98,12 +100,16 @@ export async function runTranslator(text:string, reverse:boolean, from:string,ta
async function translateMain(text:string, arg:{from:string, to:string, host:string}){
let db = get(DataBase)
if(db.translatorType === 'llm'){
const tr = db.translator || 'en'
return translateLLM(text, {to: tr})
}
if(db.translatorType === 'deepl'){
let url = db.deeplOptions.freeApi ? "https://api-free.deepl.com/v2/translate" : "https://api.deepl.com/v2/translate"
const f = await globalFetch(url, {
headers: {
"Authorization": "DeepL-Auth-Key " + db.deeplOptions.key,
"Content-Type": "application/json"
},
body: {
text: text,
@@ -162,9 +168,23 @@ async function jaTrans(text:string) {
return await runTranslator(text, true, 'en','ja')
}
export function isExpTranslator(){
const db = get(DataBase)
return db.translatorType === 'llm' || db.translatorType === 'deepl'
}
export async function translateHTML(html: string, reverse:boolean): Promise<string> {
let db = get(DataBase)
let DoingChat = get(doingChat)
if(DoingChat){
if(isExpTranslator()){
return html
}
}
if(db.translatorType === 'llm'){
const tr = db.translator || 'en'
return translateLLM(html, {to: tr})
}
const dom = new DOMParser().parseFromString(html, 'text/html');
console.log(html)
@@ -219,4 +239,35 @@ export async function translateHTML(html: string, reverse:boolean): Promise<stri
// console.log(translatedHTML)
// Return the translated HTML, excluding the outer <body> tags if needed
return translatedHTML
}
let llmCache = new Map<string, string>()
async function translateLLM(text:string, arg:{to:string}){
if(llmCache.has(text)){
return llmCache.get(text)
}
const db = get(DataBase)
let prompt = db.translatorPrompt || `You are a translator. translate the following html or text into {{slot}}. do not output anything other than the translation.`
prompt = prompt.replace('{{slot}}', arg.to)
const rq = await requestChatData({
formated: [
{
'role': 'system',
'content': prompt
},
{
'role': 'user',
'content': text
}
],
bias: {},
useStreaming: false,
}, 'submodel')
if(rq.type === 'fail' || rq.type === 'streaming' || rq.type === 'multiline'){
alertError(`${rq.result}`)
return text
}
llmCache.set(text, rq.result)
return rq.result
}