Merge pull request #1011 from bdashore3/generate-array
Generate: Change prompt building mechanisms
This commit is contained in:
commit
11ba93aa10
|
@ -45,6 +45,7 @@
|
|||
<script src="lib/pagination.js"></script>
|
||||
<script src="lib/toolcool-color-picker.js"></script>
|
||||
<script src="lib/svg-inject.js"></script>
|
||||
<script type="module" src="lib/structured-clone/monkey-patch.js"></script>
|
||||
<script type="module" src="lib/swiped-events.js"></script>
|
||||
<script type="module" src="lib/eventemitter.js"></script>
|
||||
<script type="module" src="scripts/power-user.js"></script>
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
ISC License
|
||||
|
||||
Copyright (c) 2021, Andrea Giammarchi, @WebReflection
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
|
@ -0,0 +1,79 @@
|
|||
import {
|
||||
VOID, PRIMITIVE,
|
||||
ARRAY, OBJECT,
|
||||
DATE, REGEXP, MAP, SET,
|
||||
ERROR, BIGINT
|
||||
} from './types.js';
|
||||
|
||||
const env = typeof self === 'object' ? self : globalThis;
|
||||
|
||||
const deserializer = ($, _) => {
|
||||
const as = (out, index) => {
|
||||
$.set(index, out);
|
||||
return out;
|
||||
};
|
||||
|
||||
const unpair = index => {
|
||||
if ($.has(index))
|
||||
return $.get(index);
|
||||
|
||||
const [type, value] = _[index];
|
||||
switch (type) {
|
||||
case PRIMITIVE:
|
||||
case VOID:
|
||||
return as(value, index);
|
||||
case ARRAY: {
|
||||
const arr = as([], index);
|
||||
for (const index of value)
|
||||
arr.push(unpair(index));
|
||||
return arr;
|
||||
}
|
||||
case OBJECT: {
|
||||
const object = as({}, index);
|
||||
for (const [key, index] of value)
|
||||
object[unpair(key)] = unpair(index);
|
||||
return object;
|
||||
}
|
||||
case DATE:
|
||||
return as(new Date(value), index);
|
||||
case REGEXP: {
|
||||
const {source, flags} = value;
|
||||
return as(new RegExp(source, flags), index);
|
||||
}
|
||||
case MAP: {
|
||||
const map = as(new Map, index);
|
||||
for (const [key, index] of value)
|
||||
map.set(unpair(key), unpair(index));
|
||||
return map;
|
||||
}
|
||||
case SET: {
|
||||
const set = as(new Set, index);
|
||||
for (const index of value)
|
||||
set.add(unpair(index));
|
||||
return set;
|
||||
}
|
||||
case ERROR: {
|
||||
const {name, message} = value;
|
||||
return as(new env[name](message), index);
|
||||
}
|
||||
case BIGINT:
|
||||
return as(BigInt(value), index);
|
||||
case 'BigInt':
|
||||
return as(Object(BigInt(value)), index);
|
||||
}
|
||||
return as(new env[type](value), index);
|
||||
};
|
||||
|
||||
return unpair;
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {Array<string,any>} Record a type representation
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns a deserialized value from a serialized array of Records.
|
||||
* @param {Record[]} serialized a previously serialized value.
|
||||
* @returns {any}
|
||||
*/
|
||||
export const deserialize = serialized => deserializer(new Map, serialized)(0);
|
|
@ -0,0 +1,25 @@
|
|||
import {deserialize} from './deserialize.js';
|
||||
import {serialize} from './serialize.js';
|
||||
|
||||
/**
|
||||
* @typedef {Array<string,any>} Record a type representation
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns an array of serialized Records.
|
||||
* @param {any} any a serializable value.
|
||||
* @param {{transfer?: any[], json?: boolean, lossy?: boolean}?} options an object with
|
||||
* a transfer option (ignored when polyfilled) and/or non standard fields that
|
||||
* fallback to the polyfill if present.
|
||||
* @returns {Record[]}
|
||||
*/
|
||||
export default typeof structuredClone === "function" ?
|
||||
/* c8 ignore start */
|
||||
(any, options) => (
|
||||
options && ('json' in options || 'lossy' in options) ?
|
||||
deserialize(serialize(any, options)) : structuredClone(any)
|
||||
) :
|
||||
(any, options) => deserialize(serialize(any, options));
|
||||
/* c8 ignore stop */
|
||||
|
||||
export {deserialize, serialize};
|
|
@ -0,0 +1,21 @@
|
|||
/*! (c) Andrea Giammarchi - ISC */
|
||||
|
||||
import {deserialize} from './deserialize.js';
|
||||
import {serialize} from './serialize.js';
|
||||
|
||||
const {parse: $parse, stringify: $stringify} = JSON;
|
||||
const options = {json: true, lossy: true};
|
||||
|
||||
/**
|
||||
* Revive a previously stringified structured clone.
|
||||
* @param {string} str previously stringified data as string.
|
||||
* @returns {any} whatever was previously stringified as clone.
|
||||
*/
|
||||
export const parse = str => deserialize($parse(str));
|
||||
|
||||
/**
|
||||
* Represent a structured clone value as string.
|
||||
* @param {any} any some clone-able value to stringify.
|
||||
* @returns {string} the value stringified.
|
||||
*/
|
||||
export const stringify = any => $stringify(serialize(any, options));
|
|
@ -0,0 +1,6 @@
|
|||
import structuredClone from './index.js';
|
||||
|
||||
if (!("structuredClone" in globalThis)) {
|
||||
console.debug("Monkey-patching structuredClone");
|
||||
globalThis.structuredClone = structuredClone;
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
import {
|
||||
VOID, PRIMITIVE,
|
||||
ARRAY, OBJECT,
|
||||
DATE, REGEXP, MAP, SET,
|
||||
ERROR, BIGINT
|
||||
} from './types.js';
|
||||
|
||||
const EMPTY = '';
|
||||
|
||||
const {toString} = {};
|
||||
const {keys} = Object;
|
||||
|
||||
const typeOf = value => {
|
||||
const type = typeof value;
|
||||
if (type !== 'object' || !value)
|
||||
return [PRIMITIVE, type];
|
||||
|
||||
const asString = toString.call(value).slice(8, -1);
|
||||
switch (asString) {
|
||||
case 'Array':
|
||||
return [ARRAY, EMPTY];
|
||||
case 'Object':
|
||||
return [OBJECT, EMPTY];
|
||||
case 'Date':
|
||||
return [DATE, EMPTY];
|
||||
case 'RegExp':
|
||||
return [REGEXP, EMPTY];
|
||||
case 'Map':
|
||||
return [MAP, EMPTY];
|
||||
case 'Set':
|
||||
return [SET, EMPTY];
|
||||
}
|
||||
|
||||
if (asString.includes('Array'))
|
||||
return [ARRAY, asString];
|
||||
|
||||
if (asString.includes('Error'))
|
||||
return [ERROR, asString];
|
||||
|
||||
return [OBJECT, asString];
|
||||
};
|
||||
|
||||
const shouldSkip = ([TYPE, type]) => (
|
||||
TYPE === PRIMITIVE &&
|
||||
(type === 'function' || type === 'symbol')
|
||||
);
|
||||
|
||||
const serializer = (strict, json, $, _) => {
|
||||
|
||||
const as = (out, value) => {
|
||||
const index = _.push(out) - 1;
|
||||
$.set(value, index);
|
||||
return index;
|
||||
};
|
||||
|
||||
const pair = value => {
|
||||
if ($.has(value))
|
||||
return $.get(value);
|
||||
|
||||
let [TYPE, type] = typeOf(value);
|
||||
switch (TYPE) {
|
||||
case PRIMITIVE: {
|
||||
let entry = value;
|
||||
switch (type) {
|
||||
case 'bigint':
|
||||
TYPE = BIGINT;
|
||||
entry = value.toString();
|
||||
break;
|
||||
case 'function':
|
||||
case 'symbol':
|
||||
if (strict)
|
||||
throw new TypeError('unable to serialize ' + type);
|
||||
entry = null;
|
||||
break;
|
||||
case 'undefined':
|
||||
return as([VOID], value);
|
||||
}
|
||||
return as([TYPE, entry], value);
|
||||
}
|
||||
case ARRAY: {
|
||||
if (type)
|
||||
return as([type, [...value]], value);
|
||||
|
||||
const arr = [];
|
||||
const index = as([TYPE, arr], value);
|
||||
for (const entry of value)
|
||||
arr.push(pair(entry));
|
||||
return index;
|
||||
}
|
||||
case OBJECT: {
|
||||
if (type) {
|
||||
switch (type) {
|
||||
case 'BigInt':
|
||||
return as([type, value.toString()], value);
|
||||
case 'Boolean':
|
||||
case 'Number':
|
||||
case 'String':
|
||||
return as([type, value.valueOf()], value);
|
||||
}
|
||||
}
|
||||
|
||||
if (json && ('toJSON' in value))
|
||||
return pair(value.toJSON());
|
||||
|
||||
const entries = [];
|
||||
const index = as([TYPE, entries], value);
|
||||
for (const key of keys(value)) {
|
||||
if (strict || !shouldSkip(typeOf(value[key])))
|
||||
entries.push([pair(key), pair(value[key])]);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
case DATE:
|
||||
return as([TYPE, value.toISOString()], value);
|
||||
case REGEXP: {
|
||||
const {source, flags} = value;
|
||||
return as([TYPE, {source, flags}], value);
|
||||
}
|
||||
case MAP: {
|
||||
const entries = [];
|
||||
const index = as([TYPE, entries], value);
|
||||
for (const [key, entry] of value) {
|
||||
if (strict || !(shouldSkip(typeOf(key)) || shouldSkip(typeOf(entry))))
|
||||
entries.push([pair(key), pair(entry)]);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
case SET: {
|
||||
const entries = [];
|
||||
const index = as([TYPE, entries], value);
|
||||
for (const entry of value) {
|
||||
if (strict || !shouldSkip(typeOf(entry)))
|
||||
entries.push(pair(entry));
|
||||
}
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
const {message} = value;
|
||||
return as([TYPE, {name: type, message}], value);
|
||||
};
|
||||
|
||||
return pair;
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {Array<string,any>} Record a type representation
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns an array of serialized Records.
|
||||
* @param {any} value a serializable value.
|
||||
* @param {{json?: boolean, lossy?: boolean}?} options an object with a `lossy` or `json` property that,
|
||||
* if `true`, will not throw errors on incompatible types, and behave more
|
||||
* like JSON stringify would behave. Symbol and Function will be discarded.
|
||||
* @returns {Record[]}
|
||||
*/
|
||||
export const serialize = (value, {json, lossy} = {}) => {
|
||||
const _ = [];
|
||||
return serializer(!(json || lossy), !!json, new Map, _)(value), _;
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
export const VOID = -1;
|
||||
export const PRIMITIVE = 0;
|
||||
export const ARRAY = 1;
|
||||
export const OBJECT = 2;
|
||||
export const DATE = 3;
|
||||
export const REGEXP = 4;
|
||||
export const MAP = 5;
|
||||
export const SET = 6;
|
||||
export const ERROR = 7;
|
||||
export const BIGINT = 8;
|
||||
// export const SYMBOL = 9;
|
132
public/script.js
132
public/script.js
|
@ -157,7 +157,7 @@ import {
|
|||
} from "./scripts/secrets.js";
|
||||
import { EventEmitter } from './lib/eventemitter.js';
|
||||
import { markdownExclusionExt } from "./scripts/showdown-exclusion.js";
|
||||
import { NOTE_MODULE_NAME, metadata_keys, setFloatingPrompt, shouldWIAddPrompt } from "./scripts/authors-note.js";
|
||||
import { NOTE_MODULE_NAME, initAuthorsNote, metadata_keys, setFloatingPrompt, shouldWIAddPrompt } from "./scripts/authors-note.js";
|
||||
import { getDeviceInfo } from "./scripts/RossAscends-mods.js";
|
||||
import { registerPromptManagerMigration } from "./scripts/PromptManager.js";
|
||||
import { getRegexedString, regex_placement } from "./scripts/extensions/regex/engine.js";
|
||||
|
@ -2613,7 +2613,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
console.debug('generating prompt');
|
||||
chatString = "";
|
||||
arrMes = arrMes.reverse();
|
||||
arrMes.forEach(function (item, i, arr) {//For added anchors and others
|
||||
arrMes.forEach(function (item, i, arr) {// For added anchors and others
|
||||
// OAI doesn't need all of this
|
||||
if (main_api === 'openai') {
|
||||
return;
|
||||
|
@ -2629,25 +2629,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
}
|
||||
}
|
||||
|
||||
if (i === 0) {
|
||||
// Process those that couldn't get that far
|
||||
for (let upperDepth = 100; upperDepth >= arrMes.length; upperDepth--) {
|
||||
const upperAnchor = getExtensionPrompt(extension_prompt_types.IN_CHAT, upperDepth);
|
||||
if (upperAnchor && upperAnchor.length) {
|
||||
item = upperAnchor + item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const anchorDepth = Math.abs(i - arrMes.length + 1);
|
||||
// NOTE: Depth injected here!
|
||||
const extensionAnchor = getExtensionPrompt(extension_prompt_types.IN_CHAT, anchorDepth);
|
||||
|
||||
if (anchorDepth > 0 && extensionAnchor && extensionAnchor.length) {
|
||||
item += extensionAnchor;
|
||||
}
|
||||
|
||||
mesSend[mesSend.length] = item;
|
||||
mesSend[mesSend.length] = { message: item, extensionPrompts: [] };
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2662,7 +2644,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
mesExmString = pinExmString ?? mesExamplesArray.slice(0, count_exm_add).join('');
|
||||
|
||||
if (mesSend.length) {
|
||||
mesSend[mesSend.length - 1] = modifyLastPromptLine(mesSend[mesSend.length - 1]);
|
||||
mesSend[mesSend.length - 1].message = modifyLastPromptLine(mesSend[mesSend.length - 1].message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2761,6 +2743,10 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
|
||||
// Fetches the combined prompt for both negative and positive prompts
|
||||
const cfgGuidanceScale = getGuidanceScale();
|
||||
|
||||
// For prompt bit itemization
|
||||
let mesSendString = '';
|
||||
|
||||
function getCombinedPrompt(isNegative) {
|
||||
// Only return if the guidance scale doesn't exist or the value is 1
|
||||
// Also don't return if constructing the neutral prompt
|
||||
|
@ -2768,7 +2754,50 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
return;
|
||||
}
|
||||
|
||||
let finalMesSend = [...mesSend];
|
||||
// OAI has its own prompt manager. No need to do anything here
|
||||
if (main_api === 'openai') {
|
||||
return ''
|
||||
}
|
||||
|
||||
// Deep clone
|
||||
let finalMesSend = structuredClone(mesSend);
|
||||
|
||||
// TODO: Rewrite getExtensionPrompt to not require multiple for loops
|
||||
// Set all extension prompts where insertion depth > mesSend length
|
||||
if (finalMesSend.length) {
|
||||
for (let upperDepth = 100; upperDepth >= finalMesSend.length; upperDepth--) {
|
||||
const upperAnchor = getExtensionPrompt(extension_prompt_types.IN_CHAT, upperDepth);
|
||||
if (upperAnchor && upperAnchor.length) {
|
||||
finalMesSend[0].extensionPrompts.push(upperAnchor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finalMesSend.forEach((mesItem, index) => {
|
||||
if (index === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const anchorDepth = Math.abs(index - finalMesSend.length + 1);
|
||||
// NOTE: Depth injected here!
|
||||
const extensionAnchor = getExtensionPrompt(extension_prompt_types.IN_CHAT, anchorDepth);
|
||||
|
||||
if (anchorDepth > 0 && extensionAnchor && extensionAnchor.length) {
|
||||
mesItem.extensionPrompts.push(extensionAnchor);
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: Move zero-depth anchor append to work like CFG and bias appends
|
||||
if (zeroDepthAnchor && zeroDepthAnchor.length) {
|
||||
if (!isMultigenEnabled() || tokens_already_generated == 0) {
|
||||
console.log(/\s/.test(finalMesSend[finalMesSend.length - 1].message.slice(-1)))
|
||||
finalMesSend[finalMesSend.length - 1].message +=
|
||||
/\s/.test(finalMesSend[finalMesSend.length - 1].message.slice(-1))
|
||||
? zeroDepthAnchor
|
||||
: `${zeroDepthAnchor}`;
|
||||
}
|
||||
}
|
||||
|
||||
let cfgPrompt = {};
|
||||
if (cfgGuidanceScale && cfgGuidanceScale?.value !== 1) {
|
||||
cfgPrompt = getCfgPrompt(cfgGuidanceScale, isNegative);
|
||||
|
@ -2776,13 +2805,13 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
|
||||
if (cfgPrompt && cfgPrompt?.value) {
|
||||
if (cfgPrompt?.depth === 0) {
|
||||
finalMesSend[finalMesSend.length - 1] +=
|
||||
/\s/.test(finalMesSend[finalMesSend.length - 1].slice(-1))
|
||||
finalMesSend[finalMesSend.length - 1].message +=
|
||||
/\s/.test(finalMesSend[finalMesSend.length - 1].message.slice(-1))
|
||||
? cfgPrompt.value
|
||||
: ` ${cfgPrompt.value}`;
|
||||
} else {
|
||||
// TODO: Make all extension prompts use an array/splice method
|
||||
finalMesSend.splice(mesSend.length - cfgPrompt.depth, 0, `${cfgPrompt.value}\n`);
|
||||
finalMesSend[mesSend.length - cfgPrompt.depth].extensionPrompts.push(`${cfgPrompt.value}\n`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2790,25 +2819,20 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
// Always run with continue
|
||||
if (!isInstruct && !isImpersonate && (tokens_already_generated === 0 || isContinue)) {
|
||||
if (promptBias.trim().length !== 0) {
|
||||
finalMesSend[finalMesSend.length - 1] +=
|
||||
/\s/.test(finalMesSend[finalMesSend.length - 1].slice(-1))
|
||||
finalMesSend[finalMesSend.length - 1].message +=
|
||||
/\s/.test(finalMesSend[finalMesSend.length - 1].message.slice(-1))
|
||||
? promptBias.trimStart()
|
||||
: ` ${promptBias.trimStart()}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Prune from prompt cache if it exists
|
||||
if (generatedPromtCache.length !== 0) {
|
||||
generatedPromtCache = cleanupPromptCache(generatedPromtCache);
|
||||
}
|
||||
|
||||
// Override for prompt bits data
|
||||
if (!isNegative) {
|
||||
mesSend = finalMesSend;
|
||||
}
|
||||
|
||||
let mesSendString = finalMesSend.join('');
|
||||
// Right now, everything is suffixed with a newline
|
||||
mesSendString = finalMesSend.map((e) => `${e.extensionPrompts.join('')}${e.message}`).join('');
|
||||
|
||||
// add chat preamble
|
||||
mesSendString = addChatsPreamble(mesSendString);
|
||||
|
@ -2823,13 +2847,6 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
mesSendString +
|
||||
generatedPromtCache;
|
||||
|
||||
// TODO: Move zero-depth anchor append to work like CFG and bias appends
|
||||
if (zeroDepthAnchor && zeroDepthAnchor.length) {
|
||||
if (!isMultigenEnabled() || tokens_already_generated == 0) {
|
||||
combinedPrompt = appendZeroDepthAnchor(force_name2, zeroDepthAnchor, combinedPrompt);
|
||||
}
|
||||
}
|
||||
|
||||
combinedPrompt = combinedPrompt.replace(/\r/gm, '');
|
||||
|
||||
if (power_user.collapse_newlines) {
|
||||
|
@ -2841,7 +2858,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
|
||||
// Get the negative prompt first since it has the unmodified mesSend array
|
||||
let negativePrompt = main_api == 'textgenerationwebui' ? getCombinedPrompt(true) : undefined;
|
||||
let finalPromt = getCombinedPrompt(false);
|
||||
let finalPrompt = getCombinedPrompt(false);
|
||||
|
||||
// Include the entire guidance scale object
|
||||
const cfgValues = cfgGuidanceScale && cfgGuidanceScale?.value !== 1 ? ({ guidanceScale: cfgGuidanceScale, negativePrompt: negativePrompt }) : null;
|
||||
|
@ -2865,7 +2882,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
let generate_data;
|
||||
if (main_api == 'koboldhorde' || main_api == 'kobold') {
|
||||
generate_data = {
|
||||
prompt: finalPromt,
|
||||
prompt: finalPrompt,
|
||||
gui_settings: true,
|
||||
max_length: amount_gen,
|
||||
temperature: kai_settings.temp,
|
||||
|
@ -2875,16 +2892,16 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
|
||||
if (preset_settings != 'gui') {
|
||||
const maxContext = (adjustedParams && horde_settings.auto_adjust_context_length) ? adjustedParams.maxContextLength : max_context;
|
||||
generate_data = getKoboldGenerationData(finalPromt, this_settings, this_amount_gen, maxContext, isImpersonate, type);
|
||||
generate_data = getKoboldGenerationData(finalPrompt, this_settings, this_amount_gen, maxContext, isImpersonate, type);
|
||||
}
|
||||
}
|
||||
else if (main_api == 'textgenerationwebui') {
|
||||
generate_data = getTextGenGenerationData(finalPromt, this_amount_gen, isImpersonate, cfgValues);
|
||||
generate_data = getTextGenGenerationData(finalPrompt, this_amount_gen, isImpersonate, cfgValues);
|
||||
generate_data.use_mancer = api_use_mancer_webui;
|
||||
}
|
||||
else if (main_api == 'novel') {
|
||||
const this_settings = novelai_settings[novelai_setting_names[nai_settings.preset_settings_novel]];
|
||||
generate_data = getNovelGenerationData(finalPromt, this_settings, this_amount_gen, isImpersonate, cfgValues);
|
||||
generate_data = getNovelGenerationData(finalPrompt, this_settings, this_amount_gen, isImpersonate, cfgValues);
|
||||
}
|
||||
else if (main_api == 'openai') {
|
||||
let [prompt, counts] = prepareOpenAIMessages({
|
||||
|
@ -2940,10 +2957,10 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
storyString: storyString,
|
||||
afterScenarioAnchor: afterScenarioAnchor,
|
||||
examplesString: examplesString,
|
||||
mesSendString: mesSend.join(''),
|
||||
mesSendString: mesSendString,
|
||||
generatedPromtCache: generatedPromtCache,
|
||||
promptBias: promptBias,
|
||||
finalPromt: finalPromt,
|
||||
finalPromt: finalPrompt,
|
||||
charDescription: charDescription,
|
||||
charPersonality: charPersonality,
|
||||
scenarioText: scenarioText,
|
||||
|
@ -2970,7 +2987,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
}
|
||||
}
|
||||
else if (main_api == 'koboldhorde') {
|
||||
generateHorde(finalPromt, generate_data, abortController.signal).then(onSuccess).catch(onError);
|
||||
generateHorde(finalPrompt, generate_data, abortController.signal).then(onSuccess).catch(onError);
|
||||
}
|
||||
else if (main_api == 'textgenerationwebui' && isStreamingEnabled() && type !== 'quiet') {
|
||||
streamingProcessor.generator = await generateTextGenWithStreaming(generate_data, streamingProcessor.abortController.signal);
|
||||
|
@ -5844,10 +5861,22 @@ function select_rm_characters() {
|
|||
printCharacters(false); // Do a quick refresh of the characters list
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a prompt injection to insert custom text into any outgoing prompt. For use in UI extensions.
|
||||
* @param {string} key Prompt injection id.
|
||||
* @param {string} value Prompt injection value.
|
||||
* @param {number} position Insertion position. 0 is after story string, 1 is in-chat with custom depth.
|
||||
* @param {number} depth Insertion depth. 0 represets the last message in context. Expected values up to 100.
|
||||
*/
|
||||
function setExtensionPrompt(key, value, position, depth) {
|
||||
extension_prompts[key] = { value, position, depth };
|
||||
extension_prompts[key] = { value: String(value), position: Number(position), depth: Number(depth) };
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds or updates the metadata for the currently active chat.
|
||||
* @param {Object} newValues An object with collection of new values to be added into the metadata.
|
||||
* @param {boolean} reset Should a metadata be reset by this call.
|
||||
*/
|
||||
function updateChatMetadata(newValues, reset) {
|
||||
chat_metadata = reset ? { ...newValues } : { ...chat_metadata, ...newValues };
|
||||
}
|
||||
|
@ -9035,5 +9064,6 @@ $(document).ready(function () {
|
|||
});
|
||||
|
||||
// Added here to prevent execution before script.js is loaded and get rid of quirky timeouts
|
||||
initAuthorsNote();
|
||||
initRossMods();
|
||||
});
|
||||
|
|
|
@ -389,10 +389,11 @@ function onChatChanged() {
|
|||
$('#extension_floating_default_token_counter').text(tokenCounter3);
|
||||
}
|
||||
|
||||
// Inject extension when extensions_activating is fired
|
||||
/**
|
||||
* Inject author's note options and setup event listeners.
|
||||
*/
|
||||
// Inserts the extension first since it's statically imported
|
||||
jQuery(async () => {
|
||||
await waitUntilCondition(() => eventSource !== undefined);
|
||||
export function initAuthorsNote() {
|
||||
$('#extension_floating_prompt').on('input', onExtensionFloatingPromptInput);
|
||||
$('#extension_floating_interval').on('input', onExtensionFloatingIntervalInput);
|
||||
$('#extension_floating_depth').on('input', onExtensionFloatingDepthInput);
|
||||
|
@ -419,4 +420,4 @@ jQuery(async () => {
|
|||
registerSlashCommand('freq', setNoteIntervalCommand, ['interval'], "<span class='monospace'>(number)</span> – sets an author's note insertion frequency", true, true);
|
||||
registerSlashCommand('pos', setNotePositionCommand, ['position'], "(<span class='monospace'>chat</span> or <span class='monospace'>scenario</span>) – sets an author's note position", true, true);
|
||||
eventSource.on(event_types.CHAT_CHANGED, onChatChanged);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -296,11 +296,11 @@ function setOpenAIMessages(chat) {
|
|||
}
|
||||
|
||||
// Add chat injections, 100 = maximum depth of injection. (Why would you ever need more?)
|
||||
for (let i = 0; i < 100; i++) {
|
||||
for (let i = 100; i >= 0; i--) {
|
||||
const anchor = getExtensionPrompt(extension_prompt_types.IN_CHAT, i);
|
||||
|
||||
if (anchor && anchor.length) {
|
||||
openai_msgs.splice(i, 0, { "role": 'system', 'content': anchor.trim() })
|
||||
openai_msgs.splice(i, 0, { "role": 'system', 'content': anchor.trim() });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue