Add v3 writing and decorators

This commit is contained in:
kwaroran 2024-07-11 15:11:35 +09:00
parent adc3eeea51
commit c3185d34c7
2 changed files with 88 additions and 2 deletions

View File

@ -108,6 +108,7 @@ const METADATA_KEY = 'world_info';
const DEFAULT_DEPTH = 4;
const DEFAULT_WEIGHT = 100;
const MAX_SCAN_DEPTH = 1000;
const KNOWN_DECORATORS = ['@@activate', '@@dont_activate']
// Typedef area
/**
@ -3531,6 +3532,61 @@ export async function getSortedEntries() {
}
}
/**
* Parse decorators from worldinfo content
* @param {string} content The content to parse
* @returns {[string[],string]} The decorators found in the content and the content without decorators
*/
function parseDecorators(content){
/**
* Check if the decorator is known
* @param {string} data string to check
* @returns {boolean} true if the decorator is known
*/
const isKnownDecorator = (data) => {
if(data.startsWith('@@@')){
data = data.substring(1)
}
for(let i = 0; i<KNOWN_DECORATORS.length;i++){
if(data.startsWith(KNOWN_DECORATORS[i])){
return true
}
}
return false
}
if(content.startsWith('@@')){
let newContent = content;
const splited = content.split('\n');
let decorators = []
let fallbacked = false;
for (let i = 0; i < splited.length; i++) {
if(splited[i].startsWith('@@')){
if(splited[i].startsWith('@@@') && !fallbacked){
continue
}
if(isKnownDecorator(splited[i])){
decorators.push(splited[i].startsWith('@@@') ? splited[i].substring(1) : splited[i])
}
else{
fallbacked = true
}
} else {
newContent = splited.slice(i).join('\n');
break;
}
}
return [decorators, newContent]
}
return [[], content]
}
/**
* Performs a scan on the chat and returns the world info activated.
* @param {string[]} chat The chat messages to scan, in reverse order.
@ -3588,6 +3644,20 @@ async function checkWorldInfo(chat, maxContext, isDryRun) {
let activatedNow = new Set();
for (let entry of sortedEntries) {
//oarse decorators
const [decorators] = parseDecorators(entry.content);
if(decorators.includes('@@activate')){
//activate in any case
activatedNow.add(entry);
continue;
}
if(decorators.includes('@@dont_activate')){
//deactivate in any case if @@activate is not present
continue;
}
// Check if this entry applies to the character or if it's excluded
if (entry.characterFilter && entry.characterFilter?.names?.length > 0) {
const nameIncluded = entry.characterFilter.names.includes(getCharaFilename());
@ -3656,6 +3726,7 @@ async function checkWorldInfo(chat, maxContext, isDryRun) {
continue;
}
if (Array.isArray(entry.key) && entry.key.length) { //check for keywords existing
// If selectiveLogic isn't found, assume it's AND, only do this once per entry
const selectiveLogic = entry.selectiveLogic ?? 0;
@ -3748,7 +3819,7 @@ async function checkWorldInfo(chat, maxContext, isDryRun) {
} else { console.debug(`uid:${entry.uid} passed probability check, inserting to prompt`); }
// Substitute macros inline, for both this checking and also future processing
entry.content = substituteParams(entry.content);
entry.content = substituteParams(parseDecorators(entry.content)[1]);
newContent += `${entry.content}\n`;
if ((textToScanTokens + (await getTokenCountAsync(newContent))) >= budget) {

View File

@ -23,9 +23,24 @@ const write = (image, data) => {
}
}
// Add new chunks before the IEND chunk
// Add new v2 chunk before the IEND chunk
const base64EncodedData = Buffer.from(data, 'utf8').toString('base64');
chunks.splice(-1, 0, PNGtext.encode('chara', base64EncodedData));
// Try adding v3 chunk before the IEND chunk
try {
//change v2 format to v3
const v3Data = JSON.parse(data);
v3Data.spec = 'chara_card_v3'
v3Data.spec_version = '3.0'
if(v3Data.data && !v3Data.data.group_only_greetings){
v3Data.data.group_only_greetings = []
}
const base64EncodedData = Buffer.from(JSON.stringify(v3Data), 'utf8').toString('base64');
chunks.splice(-1, 0, PNGtext.encode('ccv3', base64EncodedData));
} catch (error) {}
const newBuffer = Buffer.from(encode(chunks));
return newBuffer;
};