[feat] added horde support, added spec2 requirements that didn't implemented

This commit is contained in:
kwaroran
2023-05-24 08:49:35 +09:00
parent 022f70f214
commit a999d6d780
9 changed files with 214 additions and 62 deletions

View File

@@ -203,7 +203,8 @@ function convertOldTavernAndJSON(charaData:OldTavernChar, imgp:string|undefined
characterVersion: 0,
personality: charaData.personality ?? '',
scenario:charaData.scenario ?? '',
firstMsgIndex: -1
firstMsgIndex: -1,
replaceGlobalNote: ""
}
}
@@ -381,7 +382,7 @@ async function importSpecv2(card:CharacterCardV2, img?:Uint8Array):Promise<boole
mode: "normal",
alwaysActive: book.constant ?? 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 ?? '',
creatorNotes:data.creator_notes ?? '',
systemPrompt:data.system_prompt ?? '',
postHistoryInstructions:data.post_history_instructions ?? '',
postHistoryInstructions:'',
alternateGreetings:data.alternate_greetings ?? [],
tags:data.tags ?? [],
creator:data.creator ?? '',
@@ -428,7 +429,8 @@ async function importSpecv2(card:CharacterCardV2, img?:Uint8Array):Promise<boole
creator: data.creator,
character_version: data.character_version
},
additionalAssets: extAssets
additionalAssets: extAssets,
replaceGlobalNote: data.post_history_instructions ?? ''
}
db.characters.push(char)
@@ -458,7 +460,8 @@ export async function exportSpecV2(char:character) {
constant: lore.alwaysActive,
selective:lore.selective,
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,
creator_notes: char.creatorNotes,
system_prompt: char.systemPrompt,
post_history_instructions: char.postHistoryInstructions,
post_history_instructions: char.replaceGlobalNote,
alternate_greetings: char.alternateGreetings,
character_book: {
scan_depth: char.loreSettings?.scanDepth,
@@ -625,5 +628,5 @@ interface charBookEntry{
secondary_keys?: Array<string> // see field `selective`. ignored if selective == false
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
case_sensitive?:boolean
}

View File

@@ -275,7 +275,6 @@ export function characterFormatUpdate(index:number|character){
cha.exampleMessage = cha.exampleMessage ?? ''
cha.creatorNotes = cha.creatorNotes ?? ''
cha.systemPrompt = cha.systemPrompt ?? ''
cha.postHistoryInstructions = cha.postHistoryInstructions ?? ''
cha.tags = cha.tags ?? []
cha.creator = cha.creator ?? ''
cha.characterVersion = cha.characterVersion ?? 0
@@ -288,6 +287,12 @@ export function characterFormatUpdate(index:number|character){
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)){
cha.customscript = []
@@ -332,7 +337,8 @@ export function createBlankChar():character{
characterVersion: 0,
personality:"",
scenario:"",
firstMsgIndex: -1
firstMsgIndex: -1,
replaceGlobalNote: ""
}
}

View File

@@ -259,7 +259,9 @@ export interface loreBook{
mode: 'multiple'|'constant'|'normal',
alwaysActive: boolean
selective:boolean
extentions?:{}
extentions?:{
risu_case_sensitive:boolean
}
}
export interface character{
@@ -303,6 +305,7 @@ export interface character{
supaMemory?:boolean
additionalAssets?:[string, string][]
ttsReadOnlyQuoted?:boolean
replaceGlobalNote:string
}

34
src/ts/horde/getModels.ts Normal file
View 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
}
}

View File

@@ -105,7 +105,7 @@ export async function sendChat(chatProcessIndex = -1):Promise<boolean> {
}
if(!currentChar.utilityBot){
const mainp = currentChar.systemPrompt.length > 3 ? currentChar.systemPrompt : db.mainPrompt
const mainp = currentChar.systemPrompt || db.mainPrompt
unformated.main.push({
role: 'system',
@@ -121,14 +121,14 @@ export async function sendChat(chatProcessIndex = -1):Promise<boolean> {
unformated.globalNote.push({
role: 'system',
content: replacePlaceholders(db.globalNote, currentChar.name)
content: replacePlaceholders(currentChar.replaceGlobalNote || db.globalNote, currentChar.name)
})
}
if(currentChat.note !== ''){
unformated.authorNote.push({
role: 'system',
content: replacePlaceholders(currentChar.postHistoryInstructions, currentChat.note)
content: replacePlaceholders(currentChat.note, currentChar.name)
})
}

View File

@@ -5,6 +5,8 @@ import { pluginProcess } from "./plugins";
import { language } from "../../lang";
import { stringlizeChat, unstringlizeChat } from "./stringlize";
import { globalFetch, isTauri } from "../globalApi";
import { alertError } from "../alert";
import { sleep } from "../util";
interface requestDataArgument{
formated: OpenAIChat[]
@@ -34,7 +36,7 @@ export async function requestChatData(arg:requestDataArgument, model:'model'|'su
return da
}
trys += 1
if(trys > db.requestRetrys){
if(trys > db.requestRetrys || model.startsWith('horde')){
return da
}
}
@@ -411,7 +413,107 @@ 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 {
type: 'fail',
result: (language.errors.unknownModel)