mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge branch 'dev' of https://github.com/Cohee1207/SillyTavern into dev
This commit is contained in:
@ -1,4 +1,7 @@
|
||||
import { generateQuietPrompt } from "../../../script.js";
|
||||
import { getContext, saveMetadataDebounced } from "../../extensions.js";
|
||||
import { registerSlashCommand } from "../../slash-commands.js";
|
||||
import { stringFormat } from "../../utils.js";
|
||||
export { MODULE_NAME };
|
||||
|
||||
const MODULE_NAME = 'backgrounds';
|
||||
@ -87,6 +90,30 @@ function onSelectBackgroundClick() {
|
||||
}
|
||||
}
|
||||
|
||||
const autoBgPrompt = `Pause your roleplay and choose a location ONLY from the provided list that is the most suitable for the current scene. Do not output any other text:\n{0}`;
|
||||
|
||||
async function autoBackgroundCommand() {
|
||||
const options = Array.from(document.querySelectorAll('.BGSampleTitle')).map(x => ({ element: x, text: x.innerText.trim() })).filter(x => x.text.length > 0);
|
||||
if (options.length == 0) {
|
||||
toastr.warning('No backgrounds to choose from. Please upload some images to the "backgrounds" folder.');
|
||||
return;
|
||||
}
|
||||
|
||||
const list = options.map(option => `- ${option.text}`).join('\n');
|
||||
const prompt = stringFormat(autoBgPrompt, list);
|
||||
const reply = await generateQuietPrompt(prompt);
|
||||
const fuse = new Fuse(options, { keys: ['text'] });
|
||||
const bestMatch = fuse.search(reply, { limit: 1 });
|
||||
|
||||
if (bestMatch.length == 0) {
|
||||
toastr.warning('No match found. Please try again.');
|
||||
return;
|
||||
}
|
||||
|
||||
console.debug('Automatically choosing background:', bestMatch);
|
||||
bestMatch[0].item.element.click();
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
function addSettings() {
|
||||
const html = `
|
||||
@ -111,6 +138,16 @@ $(document).ready(function () {
|
||||
Any background image selected while lock is engaged will be saved automatically.
|
||||
</small>
|
||||
</div>
|
||||
<div class="background_controls">
|
||||
<div id="auto_background" class="menu_button">
|
||||
<i class="fa-solid fa-wand-magic"></i>
|
||||
Auto
|
||||
</div>
|
||||
<small>
|
||||
Automatically select a background based on the chat context.<br>
|
||||
Respects the "Lock" setting state.
|
||||
</small>
|
||||
</div>
|
||||
<div>Preview</div>
|
||||
<div id="custom_bg_preview">
|
||||
</div>
|
||||
@ -122,8 +159,12 @@ $(document).ready(function () {
|
||||
$('#lock_background').on('click', onLockBackgroundClick);
|
||||
$('#unlock_background').on('click', onUnlockBackgroundClick);
|
||||
$(document).on("click", ".bg_example", onSelectBackgroundClick);
|
||||
$('#auto_background').on("click", autoBackgroundCommand);
|
||||
}
|
||||
|
||||
addSettings();
|
||||
setInterval(moduleWorker, UPDATE_INTERVAL);
|
||||
registerSlashCommand('lock', onLockBackgroundClick, [], " – locks a background for the currently selected chat", true, true);
|
||||
registerSlashCommand('unlock', onUnlockBackgroundClick, [], ' – unlocks a background for the currently selected chat', true, true);
|
||||
registerSlashCommand('autobg', autoBackgroundCommand, ['bgauto'], ' – automatically changes the background based on the chat context', true, true);
|
||||
});
|
||||
|
@ -904,7 +904,9 @@ function setExpressionOverrideHtml(forceClear = false) {
|
||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
||||
</div>
|
||||
<div class="inline-drawer-content">
|
||||
<p class="offline_mode">You are in offline mode. Click on the image below to set the expression.</p>
|
||||
<div class="offline_mode">
|
||||
<small>You are in offline mode. Click on the image below to set the expression.</small>
|
||||
</div>
|
||||
<div class="flex-container flexnowrap">
|
||||
<input id="expression_override" type="text" class="text_pole" placeholder="Override folder name" />
|
||||
<input id="expression_override_button" class="menu_button" type="submit" value="Submit" />
|
||||
|
@ -143,11 +143,6 @@ img.expression.default {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.expression_settings p {
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.expression_settings label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -171,4 +166,4 @@ img.expression.default {
|
||||
div.expression {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,9 @@ import {
|
||||
substituteParams,
|
||||
eventSource,
|
||||
event_types,
|
||||
generateQuietPrompt,
|
||||
} from "../../../script.js";
|
||||
import { registerSlashCommand } from "../../slash-commands.js";
|
||||
|
||||
const MODULE_NAME = "Objective"
|
||||
|
||||
@ -12,7 +14,7 @@ const MODULE_NAME = "Objective"
|
||||
let globalObjective = ""
|
||||
let globalTasks = []
|
||||
let currentChatId = ""
|
||||
let currentTask = {}
|
||||
let currentTask = null
|
||||
let checkCounter = 0
|
||||
|
||||
|
||||
@ -38,90 +40,70 @@ const objectivePrompts = {
|
||||
`
|
||||
}
|
||||
|
||||
const injectPrompts = {
|
||||
"task": "Your current task is [{{task}}]. Balance existing roleplay with completing this task."
|
||||
}
|
||||
const extensionPrompt = "Your current task is [{{task}}]. Balance existing roleplay with completing this task."
|
||||
|
||||
// Background prompt generation
|
||||
async function generateQuietPrompt(quiet_prompt) {
|
||||
return await new Promise(
|
||||
async function promptPromise(resolve, reject) {
|
||||
try {
|
||||
await getContext().generate('quiet', { resolve, reject, quiet_prompt, force_name2: true, });
|
||||
}
|
||||
catch {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//###############################//
|
||||
//# Task Management #//
|
||||
//###############################//
|
||||
|
||||
// Accepts optional position. Defaults to adding to end of list.
|
||||
function addTask(description, position = null) {
|
||||
position = position != null ? position : position = globalTasks.length
|
||||
globalTasks.splice(position, 0, {
|
||||
"description": description,
|
||||
"completed": false
|
||||
})
|
||||
// Accepts optional index. Defaults to adding to end of list.
|
||||
function addTask(description, index = null) {
|
||||
index = index != null ? index: index = globalTasks.length
|
||||
globalTasks.splice(index, 0, new ObjectiveTask(
|
||||
{description: description}
|
||||
))
|
||||
saveState()
|
||||
}
|
||||
|
||||
// Get a task either by index or task description. Return current task if none specified
|
||||
function getTask(index = null, taskDescription = null) {
|
||||
let task = {}
|
||||
if (index == null && taskDescription == null) {
|
||||
task = currentTask
|
||||
} else if (index != null) {
|
||||
task = globalObjective[index]
|
||||
} else if (taskDescription != null) {
|
||||
task = globalTasks.find(task => {
|
||||
return task.description == description ? true : false
|
||||
})
|
||||
// Return the task and index or throw an error
|
||||
function getTaskById(taskId){
|
||||
if (taskId == null) {
|
||||
throw `Null task id`
|
||||
}
|
||||
const index = globalTasks.findIndex((task) => task.id === taskId);
|
||||
if (index !== -1) {
|
||||
return { task: globalTasks[index], index: index };
|
||||
} else {
|
||||
throw `Cannot find task with ${taskId}`
|
||||
|
||||
}
|
||||
return task
|
||||
}
|
||||
|
||||
function deleteTask(index) {
|
||||
function deleteTask(taskId){
|
||||
const { task, index } = getTaskById(taskId)
|
||||
|
||||
globalTasks.splice(index, 1)
|
||||
setCurrentTask()
|
||||
updateUiTaskList()
|
||||
}
|
||||
|
||||
// Complete the current task, setting next task to next incomplete task
|
||||
function completeTask(task) {
|
||||
task.completed = true
|
||||
console.info(`Task successfully completed: ${JSON.stringify(task)}`)
|
||||
setCurrentTask()
|
||||
updateUiTaskList()
|
||||
}
|
||||
|
||||
// Call Quiet Generate to create task list using character context, then convert to tasks. Should not be called much.
|
||||
async function generateTasks() {
|
||||
const prompt = substituteParams(objectivePrompts["createTask"].replace(/{{objective}}/gi, globalObjective));
|
||||
console.log(`Generating tasks for objective with prompt`)
|
||||
toastr.info('Generating tasks for objective', 'Please wait...');
|
||||
const taskResponse = await generateQuietPrompt(prompt)
|
||||
|
||||
// Clear all existing global tasks when generating
|
||||
globalTasks = []
|
||||
const numberedListPattern = /^\d+\./
|
||||
|
||||
// Add numbered tasks, store them without the numbers.
|
||||
// Create tasks from generated task list
|
||||
for (const task of taskResponse.split('\n').map(x => x.trim())) {
|
||||
if (task.match(numberedListPattern) != null) {
|
||||
addTask(task.replace(numberedListPattern, '').trim())
|
||||
addTask(task.replace(numberedListPattern,"").trim())
|
||||
}
|
||||
}
|
||||
updateUiTaskList()
|
||||
console.info(`Response for Objective: '${globalObjective}' was \n'${taskResponse}', \nwhich created tasks \n${JSON.stringify(globalTasks, null, 2)} `)
|
||||
console.info(`Response for Objective: '${globalObjective}' was \n'${taskResponse}', \nwhich created tasks \n${JSON.stringify(globalTasks.map(v => {return v.toSaveState()}), null, 2)} `)
|
||||
toastr.success(`Generated ${globalTasks.length} tasks`, 'Done!');
|
||||
}
|
||||
|
||||
// Call Quiet Generate to check if a task is completed
|
||||
async function checkTaskCompleted() {
|
||||
// Make sure there are tasks
|
||||
if (Object.keys(currentTask).length == 0) {
|
||||
// Make sure there are tasks
|
||||
if (jQuery.isEmptyObject(currentTask)) {
|
||||
return
|
||||
}
|
||||
checkCounter = $('#objective-check-frequency').val()
|
||||
@ -131,8 +113,8 @@ async function checkTaskCompleted() {
|
||||
|
||||
// Check response if task complete
|
||||
if (taskResponse.includes("true")) {
|
||||
console.info(`Character determined task '${JSON.stringify(currentTask)} is completed.`)
|
||||
completeTask(getTask())
|
||||
console.info(`Character determined task '${JSON.stringify(currentTask.toSaveState())} is completed.`)
|
||||
currentTask.completeTask()
|
||||
} else if (!(taskResponse.includes("false"))) {
|
||||
console.warn(`checkTaskCompleted response did not contain true or false. taskResponse: ${taskResponse}`)
|
||||
} else {
|
||||
@ -142,21 +124,26 @@ async function checkTaskCompleted() {
|
||||
|
||||
|
||||
// Set a task in extensionPrompt context. Defaults to first incomplete
|
||||
function setCurrentTask(index = null) {
|
||||
function setCurrentTask(taskId = null) {
|
||||
const context = getContext();
|
||||
currentTask = {};
|
||||
|
||||
if (index === null) {
|
||||
// Set current task to either the next incomplete task, or the index
|
||||
if (taskId === null) {
|
||||
currentTask = globalTasks.find(task => !task.completed) || {};
|
||||
} else if (index >= 0 && index < globalTasks.length) {
|
||||
} else {
|
||||
const { _, index } = getTaskById(taskId)
|
||||
currentTask = globalTasks[index];
|
||||
}
|
||||
|
||||
const { description } = currentTask;
|
||||
const injectPromptsTask = injectPrompts["task"].replace(/{{task}}/gi, description);
|
||||
// Get the task description and add to extension prompt
|
||||
const description = currentTask.description || null;
|
||||
|
||||
// Now update the extension prompt
|
||||
|
||||
if (description) {
|
||||
context.setExtensionPrompt(MODULE_NAME, injectPromptsTask, 1, $('#objective-chat-depth').val());
|
||||
const extensionPromptText = extensionPrompt.replace(/{{task}}/gi, description);
|
||||
context.setExtensionPrompt(MODULE_NAME, extensionPromptText, 1, $('#objective-chat-depth').val());
|
||||
console.info(`Current task in context.extensionPrompts.Objective is ${JSON.stringify(context.extensionPrompts.Objective)}`);
|
||||
} else {
|
||||
context.setExtensionPrompt(MODULE_NAME, '');
|
||||
@ -166,7 +153,114 @@ function setCurrentTask(index = null) {
|
||||
saveState();
|
||||
}
|
||||
|
||||
let taskIdCounter = 0
|
||||
function getNextTaskId(){
|
||||
// Make sure id does not exist
|
||||
while (globalTasks.find(task => task.id == taskIdCounter) != undefined) {
|
||||
taskIdCounter += 1
|
||||
}
|
||||
const nextId = taskIdCounter
|
||||
console.log(`TaskID assigned: ${nextId}`)
|
||||
taskIdCounter += 1
|
||||
return nextId
|
||||
}
|
||||
class ObjectiveTask {
|
||||
id
|
||||
description
|
||||
completed
|
||||
parent
|
||||
children
|
||||
|
||||
// UI Elements
|
||||
taskHtml
|
||||
descriptionSpan
|
||||
completedCheckbox
|
||||
deleteTaskButton
|
||||
addTaskButton
|
||||
|
||||
constructor ({id=undefined, description, completed=false, parent=null}) {
|
||||
this.description = description
|
||||
this.parent = parent
|
||||
this.children = []
|
||||
this.completed = completed
|
||||
|
||||
// Generate a new ID if none specified
|
||||
if (id==undefined){
|
||||
this.id = getNextTaskId()
|
||||
} else {
|
||||
this.id=id
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Complete the current task, setting next task to next incomplete task
|
||||
completeTask() {
|
||||
this.completed = true
|
||||
console.info(`Task successfully completed: ${JSON.stringify(this.description)}`)
|
||||
setCurrentTask()
|
||||
updateUiTaskList()
|
||||
}
|
||||
|
||||
// Add a single task to the UI and attach event listeners for user edits
|
||||
addUiElement() {
|
||||
const template = `
|
||||
<div id="objective-task-label-${this.id}" class="flex1 checkbox_label">
|
||||
<input id="objective-task-complete-${this.id}" type="checkbox">
|
||||
<span class="text_pole" style="display: block" id="objective-task-description-${this.id}" contenteditable>${this.description}</span>
|
||||
<div id="objective-task-delete-${this.id}" class="objective-task-button fa-solid fa-xmark fa-2x" title="Delete Task"></div>
|
||||
<div id="objective-task-add-${this.id}" class="objective-task-button fa-solid fa-plus fa-2x" title="Add Task"></div>
|
||||
</div><br>
|
||||
`;
|
||||
|
||||
// Add the filled out template
|
||||
$('#objective-tasks').append(template);
|
||||
|
||||
this.completedCheckbox = $(`#objective-task-complete-${this.id}`);
|
||||
this.descriptionSpan = $(`#objective-task-description-${this.id}`);
|
||||
this.addButton = $(`#objective-task-add-${this.id}`);
|
||||
this.deleteButton = $(`#objective-task-delete-${this.id}`);
|
||||
|
||||
// Add event listeners and set properties
|
||||
$(`#objective-task-complete-${this.id}`).prop('checked', this.completed);
|
||||
$(`#objective-task-complete-${this.id}`).on('click', () => (this.onCompleteClick()));
|
||||
$(`#objective-task-description-${this.id}`).on('keyup', () => (this.onDescriptionUpdate()));
|
||||
$(`#objective-task-description-${this.id}`).on('focusout', () => (this.onDescriptionFocusout()));
|
||||
$(`#objective-task-delete-${this.id}`).on('click', () => (this.onDeleteClick()));
|
||||
$(`#objective-task-add-${this.id}`).on('click', () => (this.onAddClick()));
|
||||
}
|
||||
|
||||
onCompleteClick(){
|
||||
this.completed = this.completedCheckbox.prop('checked')
|
||||
setCurrentTask();
|
||||
}
|
||||
|
||||
onDescriptionUpdate(){
|
||||
this.description = this.descriptionSpan.text();
|
||||
}
|
||||
onDescriptionFocusout(){
|
||||
setCurrentTask();
|
||||
}
|
||||
|
||||
onDeleteClick(){
|
||||
deleteTask(this.id);
|
||||
}
|
||||
|
||||
onAddClick(){
|
||||
const {_, index} = getTaskById(this.id)
|
||||
addTask("", index + 1);
|
||||
setCurrentTask();
|
||||
updateUiTaskList();
|
||||
}
|
||||
|
||||
toSaveState() {
|
||||
return {
|
||||
"id":this.id,
|
||||
"description":this.description,
|
||||
"completed":this.completed,
|
||||
"parent": this.parent,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//###############################//
|
||||
//# UI AND Settings #//
|
||||
@ -194,9 +288,12 @@ function saveState() {
|
||||
currentChatId = context.chatId
|
||||
}
|
||||
|
||||
// Convert globalTasks for saving
|
||||
const tasks = globalTasks.map(task => {return task.toSaveState()})
|
||||
|
||||
chat_metadata['objective'] = {
|
||||
objective: globalObjective,
|
||||
tasks: globalTasks,
|
||||
tasks: tasks,
|
||||
checkFrequency: $('#objective-check-frequency').val(),
|
||||
chatDepth: $('#objective-chat-depth').val(),
|
||||
hideTasks: $('#objective-hide-tasks').prop('checked'),
|
||||
@ -208,11 +305,11 @@ function saveState() {
|
||||
// Dump core state
|
||||
function debugObjectiveExtension() {
|
||||
console.log(JSON.stringify({
|
||||
"currentTask": currentTask,
|
||||
"currentTask": currentTask.toSaveState(),
|
||||
"currentChatId": currentChatId,
|
||||
"checkCounter": checkCounter,
|
||||
"globalObjective": globalObjective,
|
||||
"globalTasks": globalTasks,
|
||||
"globalTasks": globalTasks.map(v => {return v.toSaveState()}),
|
||||
"extension_settings": chat_metadata['objective'],
|
||||
}, null, 2))
|
||||
}
|
||||
@ -220,55 +317,13 @@ function debugObjectiveExtension() {
|
||||
window.debugObjectiveExtension = debugObjectiveExtension
|
||||
|
||||
|
||||
// Add a single task to the UI and attach event listeners for user edits
|
||||
function addUiTask(taskIndex, taskComplete, taskDescription) {
|
||||
const template = `
|
||||
<div id="objective-task-label-${taskIndex}" class="flex1 checkbox_label">
|
||||
<span>${taskIndex}</span>
|
||||
<input id="objective-task-complete-${taskIndex}" type="checkbox">
|
||||
<span class="text_pole" style="display: block" id="objective-task-description-${taskIndex}" contenteditable>${taskDescription}</span>
|
||||
<div id="objective-task-delete-${taskIndex}" class="objective-task-button fa-solid fa-xmark fa-2x" title="Delete Task"></div>
|
||||
<div id="objective-task-add-${taskIndex}" class="objective-task-button fa-solid fa-plus fa-2x" title="Add Task"></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Add the filled out template
|
||||
$('#objective-tasks').append(template);
|
||||
|
||||
// Add event listeners and set properties
|
||||
$(`#objective-task-complete-${taskIndex}`).prop('checked', taskComplete);
|
||||
$(`#objective-task-complete-${taskIndex}`).on('click', event => {
|
||||
const index = Number(event.target.id.split('-').pop());
|
||||
globalTasks[index].completed = event.target.checked;
|
||||
setCurrentTask();
|
||||
});
|
||||
$(`#objective-task-description-${taskIndex}`).on('keyup', event => {
|
||||
const index = Number(event.target.id.split('-').pop());
|
||||
globalTasks[index].description = event.target.textContent;
|
||||
});
|
||||
$(`#objective-task-delete-${taskIndex}`).on('click', event => {
|
||||
const index = Number(event.target.id.split('-').pop());
|
||||
deleteTask(index)
|
||||
});
|
||||
$(`#objective-task-add-${taskIndex}`).on('click', event => {
|
||||
const index = Number(event.target.id.split('-').pop()) + 1;
|
||||
addTask("", index)
|
||||
setCurrentTask()
|
||||
updateUiTaskList()
|
||||
});
|
||||
}
|
||||
|
||||
// Populate UI task list
|
||||
function updateUiTaskList() {
|
||||
$('#objective-tasks').empty()
|
||||
// Show tasks if there are any
|
||||
if (globalTasks.length > 0) {
|
||||
for (const index in globalTasks) {
|
||||
addUiTask(
|
||||
index,
|
||||
globalTasks[index].completed,
|
||||
globalTasks[index].description
|
||||
)
|
||||
if (globalTasks.length > 0){
|
||||
for (const task of globalTasks) {
|
||||
task.addUiElement()
|
||||
}
|
||||
} else {
|
||||
// Show button to add tasks if there are none
|
||||
@ -283,14 +338,6 @@ function updateUiTaskList() {
|
||||
}
|
||||
}
|
||||
|
||||
function addManualTaskCheck() {
|
||||
$('#extensionsMenu').prepend(`
|
||||
<div id="objective-task-manual-check-menu-item" class="list-group-item flex-container flexGap5">
|
||||
<div id="objective-task-manual-check" class="extensionsMenuExtensionButton fa-regular fa-square-check"/></div>
|
||||
Manual Task Check
|
||||
</div>`)
|
||||
$('#objective-task-manual-check-menu-item').attr('title', 'Trigger AI check of completed tasks').on('click', checkTaskCompleted)
|
||||
}
|
||||
|
||||
// Trigger creation of new tasks with given objective.
|
||||
async function onGenerateObjectiveClick() {
|
||||
@ -338,7 +385,14 @@ function loadSettings() {
|
||||
|
||||
// Update globals
|
||||
globalObjective = chat_metadata['objective'].objective
|
||||
globalTasks = chat_metadata['objective'].tasks
|
||||
globalTasks = chat_metadata['objective'].tasks.map(task => {
|
||||
return new ObjectiveTask({
|
||||
id: task.id,
|
||||
description: task.description,
|
||||
completed: task.completed,
|
||||
parent: task.parent,
|
||||
})
|
||||
});
|
||||
checkCounter = chat_metadata['objective'].checkFrequency
|
||||
|
||||
// Update UI elements
|
||||
@ -352,6 +406,15 @@ function loadSettings() {
|
||||
setCurrentTask()
|
||||
}
|
||||
|
||||
function addManualTaskCheckUi() {
|
||||
$('#extensionsMenu').prepend(`
|
||||
<div id="objective-task-manual-check-menu-item" class="list-group-item flex-container flexGap5">
|
||||
<div id="objective-task-manual-check" class="extensionsMenuExtensionButton fa-regular fa-square-check"/></div>
|
||||
Manual Task Check
|
||||
</div>`)
|
||||
$('#objective-task-manual-check-menu-item').attr('title', 'Trigger AI check of completed tasks').on('click', checkTaskCompleted)
|
||||
}
|
||||
|
||||
jQuery(() => {
|
||||
const settingsHtml = `
|
||||
<div class="objective-settings">
|
||||
@ -364,18 +427,19 @@ jQuery(() => {
|
||||
<label for="objective-text"><small>Enter an objective and generate tasks. The AI will attempt to complete tasks autonomously</small></label>
|
||||
<textarea id="objective-text" type="text" class="text_pole textarea_compact" rows="4"></textarea>
|
||||
<div class="objective_block flex-container">
|
||||
<input id="objective-generate" class="menu_button" type="submit" value="Auto-Generate Tasks" />
|
||||
<input id="objective-generate" class="menu_button" type="submit" value="Auto-Generate Tasks" />
|
||||
<label class="checkbox_label"><input id="objective-hide-tasks" type="checkbox"> Hide Tasks</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="objective-tasks"> </div>
|
||||
<div class="objective_block margin-bot-10px">
|
||||
<div class="objective_block objective_block_control flex1 flexFlowColumn">
|
||||
<label for="objective-chat-depth">Position in Chat</label>
|
||||
<input id="objective-chat-depth" class="text_pole widthUnset" type="number" min="0" max="99" />
|
||||
<small>Depth</small>
|
||||
</div>
|
||||
<div class="objective_block objective_block_control flex1 flexFlowColumn">
|
||||
<br>
|
||||
<div class="objective_block objective_block_control flex1">
|
||||
|
||||
<label for="objective-check-frequency">Task Check Frequency</label>
|
||||
<input id="objective-check-frequency" class="text_pole widthUnset" type="number" min="0" max="99" />
|
||||
<small>(0 = disabled)</small>
|
||||
@ -386,7 +450,7 @@ jQuery(() => {
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
addManualTaskCheck()
|
||||
addManualTaskCheckUi()
|
||||
$('#extensions_settings').append(settingsHtml);
|
||||
$('#objective-generate').on('click', onGenerateObjectiveClick)
|
||||
$('#objective-chat-depth').on('input', onChatDepthInput)
|
||||
@ -412,4 +476,6 @@ jQuery(() => {
|
||||
setCurrentTask();
|
||||
$('#objective-counter').text(checkCounter)
|
||||
});
|
||||
|
||||
registerSlashCommand('taskcheck', checkTaskCompleted, [], ' – checks if the current task is completed', true, true);
|
||||
});
|
||||
|
@ -5,12 +5,15 @@
|
||||
|
||||
.objective_block {
|
||||
display: flex;
|
||||
/* flex-direction: row; */
|
||||
align-items: center;
|
||||
column-gap: 5px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.objective_block_control {
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.objective_block_control small,
|
||||
.objective_block_control label {
|
||||
width: max-content;
|
||||
@ -39,4 +42,4 @@
|
||||
#objective-tasks span {
|
||||
margin: unset;
|
||||
margin-bottom: 5px !important;
|
||||
}
|
||||
}
|
||||
|
2240
public/scripts/fuse.js
Normal file
2240
public/scripts/fuse.js
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user