Merge branch 'staging' into tags-as-folders-enhancements
This commit is contained in:
commit
7b49290fec
|
@ -12,11 +12,14 @@ ENTRYPOINT [ "tini", "--" ]
|
||||||
# Create app directory
|
# Create app directory
|
||||||
WORKDIR ${APP_HOME}
|
WORKDIR ${APP_HOME}
|
||||||
|
|
||||||
|
# Set NODE_ENV to production
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
# Install app dependencies
|
# Install app dependencies
|
||||||
COPY package*.json post-install.js ./
|
COPY package*.json post-install.js ./
|
||||||
RUN \
|
RUN \
|
||||||
echo "*** Install npm packages ***" && \
|
echo "*** Install npm packages ***" && \
|
||||||
npm install && npm cache clean --force
|
npm i --no-audit --no-fund --quiet --omit=dev && npm cache clean --force
|
||||||
|
|
||||||
# Bundle app source
|
# Bundle app source
|
||||||
COPY . ./
|
COPY . ./
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
pushd %~dp0
|
pushd %~dp0
|
||||||
call npm install --no-audit
|
set NODE_ENV=production
|
||||||
|
call npm install --no-audit --no-fund --quiet --omit=dev
|
||||||
node server.js %*
|
node server.js %*
|
||||||
pause
|
pause
|
||||||
popd
|
popd
|
||||||
|
|
|
@ -11,7 +11,8 @@ if %errorlevel% neq 0 (
|
||||||
echo There were errors while updating. Please download the latest version manually.
|
echo There were errors while updating. Please download the latest version manually.
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
call npm install
|
set NODE_ENV=production
|
||||||
|
call npm install --no-audit --no-fund --quiet --omit=dev
|
||||||
node server.js %*
|
node server.js %*
|
||||||
pause
|
pause
|
||||||
popd
|
popd
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -47,6 +47,9 @@
|
||||||
},
|
},
|
||||||
"axios": {
|
"axios": {
|
||||||
"follow-redirects": "^1.15.4"
|
"follow-redirects": "^1.15.4"
|
||||||
|
},
|
||||||
|
"@zeldafan0225/ai_horde": {
|
||||||
|
"esbuild": "npm:dry-uninstall"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"name": "sillytavern",
|
"name": "sillytavern",
|
||||||
|
|
|
@ -7204,6 +7204,11 @@ async function createOrEditCharacter(e) {
|
||||||
formData.set('fav', fav_ch_checked);
|
formData.set('fav', fav_ch_checked);
|
||||||
if ($('#form_create').attr('actiontype') == 'createcharacter') {
|
if ($('#form_create').attr('actiontype') == 'createcharacter') {
|
||||||
if ($('#character_name_pole').val().length > 0) {
|
if ($('#character_name_pole').val().length > 0) {
|
||||||
|
if (is_group_generating || is_send_press) {
|
||||||
|
toastr.error('Cannot create characters while generating. Stop the request and try again.', 'Creation aborted');
|
||||||
|
throw new Error('Cannot import character while generating');
|
||||||
|
}
|
||||||
|
|
||||||
//if the character name text area isn't empty (only posible when creating a new character)
|
//if the character name text area isn't empty (only posible when creating a new character)
|
||||||
let url = '/api/characters/create';
|
let url = '/api/characters/create';
|
||||||
|
|
||||||
|
@ -7956,6 +7961,11 @@ export async function processDroppedFiles(files, preserveFileNames = false) {
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async function importCharacter(file, preserveFileName = false) {
|
async function importCharacter(file, preserveFileName = false) {
|
||||||
|
if (is_group_generating || is_send_press) {
|
||||||
|
toastr.error('Cannot import characters while generating. Stop the request and try again.', 'Import aborted');
|
||||||
|
throw new Error('Cannot import character while generating');
|
||||||
|
}
|
||||||
|
|
||||||
const ext = file.name.match(/\.(\w+)$/);
|
const ext = file.name.match(/\.(\w+)$/);
|
||||||
if (!ext || !(['json', 'png', 'yaml', 'yml'].includes(ext[1].toLowerCase()))) {
|
if (!ext || !(['json', 'png', 'yaml', 'yml'].includes(ext[1].toLowerCase()))) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -76,48 +76,93 @@ class SlashCommandParser {
|
||||||
this.helpStrings[command] = stringBuilder;
|
this.helpStrings[command] = stringBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a slash command to extract the command name, the (named) arguments and the remaining text
|
||||||
|
* @param {string} text - Slash command text
|
||||||
|
* @returns {{command: string, args: object, value: string}} - The parsed command, its arguments and the remaining text
|
||||||
|
*/
|
||||||
parse(text) {
|
parse(text) {
|
||||||
|
// Parses a command even when spaces are present in arguments
|
||||||
|
// /buttons labels=["OK","I do not accept"] some text
|
||||||
|
// /fuzzy list=[ "red pink" , "yellow" ] threshold=" 0.6 " he yelled when the color was reddish and not pink | /echo
|
||||||
const excludedFromRegex = ['sendas'];
|
const excludedFromRegex = ['sendas'];
|
||||||
const firstSpace = text.indexOf(' ');
|
let command = '';
|
||||||
const command = firstSpace !== -1 ? text.substring(1, firstSpace) : text.substring(1);
|
|
||||||
let args = firstSpace !== -1 ? text.substring(firstSpace + 1) : '';
|
|
||||||
const argObj = {};
|
const argObj = {};
|
||||||
let unnamedArg;
|
let unnamedArg = '';
|
||||||
|
|
||||||
if (args.length > 0) {
|
// extract the command " /fuzzy " => "fuzzy"
|
||||||
let match;
|
text = text.trim();
|
||||||
|
let remainingText = '';
|
||||||
// Match unnamed argument
|
const commandArgPattern = /^\/([^\s]+)\s*(.*)$/s;
|
||||||
const unnamedArgPattern = /(?:\w+=(?:"(?:\\.|[^"\\])*"|\S+)\s*)*(.*)/s;
|
let match = commandArgPattern.exec(text);
|
||||||
match = unnamedArgPattern.exec(args);
|
if (match !== null && match[1].length > 0) {
|
||||||
if (match !== null && match[1].length > 0) {
|
command = match[1];
|
||||||
args = args.slice(0, -match[1].length);
|
remainingText = match[2];
|
||||||
unnamedArg = match[1].trim();
|
console.debug('command:' + command);
|
||||||
}
|
|
||||||
|
|
||||||
// Match named arguments
|
|
||||||
const namedArgPattern = /(\w+)=("(?:\\.|[^"\\])*"|\S+)/g;
|
|
||||||
while ((match = namedArgPattern.exec(args)) !== null) {
|
|
||||||
const key = match[1];
|
|
||||||
const value = match[2];
|
|
||||||
// Remove the quotes around the value, if any
|
|
||||||
argObj[key] = value.replace(/(^")|("$)/g, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Excluded commands format in their own function
|
|
||||||
if (!excludedFromRegex.includes(command)) {
|
|
||||||
unnamedArg = getRegexedString(
|
|
||||||
unnamedArg,
|
|
||||||
regex_placement.SLASH_COMMAND,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parse the rest of the string to extract named arguments, the remainder is the "unnamedArg" which is usually text, like the prompt to send
|
||||||
|
while (remainingText.length > 0) {
|
||||||
|
// does the remaining text is like nameArg=[value] or nameArg=[value,value] or nameArg=[ value , value , value]
|
||||||
|
// where value can be a string like " this is some text " , note previously it was not possible to have have spaces
|
||||||
|
// where value can be a scalar like AScalar
|
||||||
|
// where value can be a number like +9 -1005.44
|
||||||
|
// where value can be a macro like {{getvar::name}}
|
||||||
|
const namedArrayArgPattern = /^(\w+)=\[\s*(((?<quote>["'])[^"]*(\k<quote>)|{{[^}]*}}|[+-]?\d*\.?\d+|\w*)\s*,?\s*)+\]/s;
|
||||||
|
match = namedArrayArgPattern.exec(remainingText);
|
||||||
|
if (match !== null && match[0].length > 0) {
|
||||||
|
//console.log(`matching: ${match[0]}`);
|
||||||
|
const posFirstEqual = match[0].indexOf('=');
|
||||||
|
const key = match[0].substring(0, posFirstEqual).trim();
|
||||||
|
const value = match[0].substring(posFirstEqual + 1).trim();
|
||||||
|
|
||||||
|
// Remove the quotes around the value, if any
|
||||||
|
argObj[key] = value.replace(/(^")|("$)/g, '');
|
||||||
|
remainingText = remainingText.slice(match[0].length + 1).trim();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// does the remaining text is like nameArg=value
|
||||||
|
// where value can be a string like " this is some text " , note previously it was not possible to have have spaces
|
||||||
|
// where value can be a scalar like AScalar
|
||||||
|
// where value can be a number like +9 -1005.44
|
||||||
|
// where value can be a macro like {{getvar::name}}
|
||||||
|
const namedScalarArgPattern = /^(\w+)=(((?<quote>["'])[^"]*(\k<quote>)|{{[^}]*}}|[+-]?\d*\.?\d+|\w*))/s;
|
||||||
|
match = namedScalarArgPattern.exec(remainingText);
|
||||||
|
if (match !== null && match[0].length > 0) {
|
||||||
|
//console.log(`matching: ${match[0]}`);
|
||||||
|
const posFirstEqual = match[0].indexOf('=');
|
||||||
|
const key = match[0].substring(0, posFirstEqual).trim();
|
||||||
|
const value = match[0].substring(posFirstEqual + 1).trim();
|
||||||
|
|
||||||
|
// Remove the quotes around the value, if any
|
||||||
|
argObj[key] = value.replace(/(^")|("$)/g, '');
|
||||||
|
remainingText = remainingText.slice(match[0].length + 1).trim();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the remainder that matches no named argument is the "unamedArg" previously mentioned
|
||||||
|
unnamedArg = remainingText.trim();
|
||||||
|
remainingText = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Excluded commands format in their own function
|
||||||
|
if (!excludedFromRegex.includes(command)) {
|
||||||
|
console.debug(`parse: !excludedFromRegex.includes(${command}`);
|
||||||
|
console.debug(` parse: unnamedArg before: ${unnamedArg}`);
|
||||||
|
unnamedArg = getRegexedString(
|
||||||
|
unnamedArg,
|
||||||
|
regex_placement.SLASH_COMMAND,
|
||||||
|
);
|
||||||
|
console.debug(` parse: unnamedArg after: ${unnamedArg}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// your weird complex command is now transformed into a juicy tiny text or something useful :)
|
||||||
if (this.commands[command]) {
|
if (this.commands[command]) {
|
||||||
return { command: this.commands[command], args: argObj, value: unnamedArg };
|
return { command: this.commands[command], args: argObj, value: unnamedArg };
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getHelpString() {
|
getHelpString() {
|
||||||
|
|
|
@ -93,8 +93,8 @@ const cliArguments = yargs(hideBin(process.argv))
|
||||||
}).parseSync();
|
}).parseSync();
|
||||||
|
|
||||||
// change all relative paths
|
// change all relative paths
|
||||||
const serverDirectory = process['pkg'] ? path.dirname(process.execPath) : __dirname;
|
console.log(`Running in ${process.env.NODE_ENV} environment`);
|
||||||
console.log(process['pkg'] ? 'Running from binary' : 'Running from source');
|
const serverDirectory = __dirname;
|
||||||
process.chdir(serverDirectory);
|
process.chdir(serverDirectory);
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
|
@ -151,7 +151,11 @@ function convertClaudeMessages(messages, prefillString, useSysPrompt, humanMsgFi
|
||||||
// Take care of name properties since claude messages don't support them
|
// Take care of name properties since claude messages don't support them
|
||||||
mergedMessages.forEach((message) => {
|
mergedMessages.forEach((message) => {
|
||||||
if (message.name) {
|
if (message.name) {
|
||||||
message.content = `${message.name}: ${message.content}`;
|
if (Array.isArray(message.content)) {
|
||||||
|
message.content[0].text = `${message.name}: ${message.content[0].text}`;
|
||||||
|
} else {
|
||||||
|
message.content = `${message.name}: ${message.content}`;
|
||||||
|
}
|
||||||
delete message.name;
|
delete message.name;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
3
start.sh
3
start.sh
|
@ -28,7 +28,8 @@ if [ ! -z "$REPL_ID" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Installing Node Modules..."
|
echo "Installing Node Modules..."
|
||||||
npm i --no-audit
|
export NODE_ENV=production
|
||||||
|
npm i --no-audit --no-fund --quiet --omit=dev
|
||||||
|
|
||||||
echo "Entering SillyTavern..."
|
echo "Entering SillyTavern..."
|
||||||
node "$(dirname "$0")/server.js" "$@"
|
node "$(dirname "$0")/server.js" "$@"
|
||||||
|
|
Loading…
Reference in New Issue