Merge branch 'staging' into qolfeatures
This commit is contained in:
commit
a27bef8b12
|
@ -6,6 +6,7 @@ public/backgrounds/
|
|||
public/groups/
|
||||
public/group chats/
|
||||
public/worlds/
|
||||
public/user/
|
||||
public/css/bg_load.css
|
||||
public/themes/
|
||||
public/OpenAI Settings/
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/* Extensions */
|
||||
#extensions_url {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#extensions_status {
|
||||
/* margin-bottom: 10px; */
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.extensions_block input[type="submit"]:hover {
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.extensions_block input[type="checkbox"] {
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
label[for="extensions_autoconnect"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.extensions_url_block {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.extensions_url_block h4 {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.extensions_block {
|
||||
clear: both;
|
||||
padding: 0.05px;
|
||||
}
|
||||
|
||||
.extensions_info {
|
||||
text-align: left;
|
||||
margin: 0 1em;
|
||||
}
|
||||
|
||||
.extensions_info h3 {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.extensions_info h4 {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.extensions_info p {
|
||||
margin-bottom: 0.5em;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.extensions_info .disabled {
|
||||
color: lightgray;
|
||||
}
|
||||
|
||||
.extensions_info .toggle_enable {
|
||||
color: lightgreen;
|
||||
}
|
||||
|
||||
.extensions_info .toggle_disable {
|
||||
color: rgb(238, 144, 144);
|
||||
}
|
||||
|
||||
.extensions_info .extension_enabled {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.extensions_info .extension_disabled {
|
||||
color: lightgray;
|
||||
}
|
||||
|
||||
.extensions_info .extension_missing {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
input.extension_missing[type="checkbox"] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#extensions_list .disabled {
|
||||
text-decoration: line-through;
|
||||
color: lightgray;
|
||||
}
|
||||
|
||||
.update-button {
|
||||
margin-right: 10px;
|
||||
display: inline-flex;
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
.avatar_collage {
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.avatar_collage img {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.collage_2 .img_1 {
|
||||
left: 0;
|
||||
top: 0;
|
||||
max-width: 50%;
|
||||
max-height: 100%;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.collage_2 .img_2 {
|
||||
left: 50%;
|
||||
top: 0;
|
||||
max-width: 50%;
|
||||
max-height: 100%;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.collage_3 .img_1 {
|
||||
left: 0;
|
||||
top: 0;
|
||||
max-width: 50%;
|
||||
max-height: 50%;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.collage_3 .img_2 {
|
||||
left: 50%;
|
||||
top: 0;
|
||||
max-width: 50%;
|
||||
max-height: 50%;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.collage_3 .img_3 {
|
||||
left: 0;
|
||||
top: 50%;
|
||||
max-width: 100%;
|
||||
max-height: 50%;
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.collage_4 .img_1 {
|
||||
left: 0;
|
||||
top: 0;
|
||||
max-width: 50%;
|
||||
max-height: 50%;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.collage_4 .img_2 {
|
||||
left: 50%;
|
||||
top: 0;
|
||||
max-width: 50%;
|
||||
max-height: 50%;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.collage_4 .img_3 {
|
||||
left: 0;
|
||||
top: 50%;
|
||||
max-width: 50%;
|
||||
max-height: 50%;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.collage_4 .img_4 {
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
max-width: 50%;
|
||||
max-height: 50%;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
}
|
|
@ -0,0 +1,419 @@
|
|||
/*will apply to anything 1000px or less. this catches ipads, horizontal phones, and vertical phones)*/
|
||||
@media screen and (max-width: 1000px) {
|
||||
|
||||
.bg_button {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.mes_text img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#extensions_settings,
|
||||
#extensions_settings2 {
|
||||
width: 100% !important;
|
||||
min-width: 100% !important;
|
||||
}
|
||||
|
||||
body:not(.waifuMode) .zoomed_avatar {
|
||||
min-width: 100px;
|
||||
min-height: 100px;
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
filter: drop-shadow(2px 2px 2px #51515199);
|
||||
z-index: 30;
|
||||
overflow: hidden;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 auto;
|
||||
top: 50px;
|
||||
aspect-ratio: 2 / 3;
|
||||
width: fit-content;
|
||||
max-height: calc(60vh - 60px);
|
||||
max-height: calc(60svh - 60px);
|
||||
max-width: 90vw;
|
||||
max-width: 90svw;
|
||||
}
|
||||
|
||||
.world_entry_thin_controls,
|
||||
#persona-management-block,
|
||||
#character_popup .flex-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#WIMultiSelector {
|
||||
align-self: normal;
|
||||
}
|
||||
|
||||
.WIEntryContentAndMemo {
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
.WIEntryContentAndMemo .world_entry_thin_controls {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.world_entry_form_control.world_entry_form_horizontal {
|
||||
/* flex-direction: column; */
|
||||
align-items: flex-start;
|
||||
row-gap: 0.5rem;
|
||||
}
|
||||
|
||||
.world_entry_form_control.world_entry_form_horizontal .world_popup_expander {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* #world_popup_header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
} */
|
||||
|
||||
#world_popup_header .world_popup_expander {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body {
|
||||
touch-action: none;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
|
||||
}
|
||||
|
||||
.drawer-content {
|
||||
min-width: unset;
|
||||
width: 100%;
|
||||
max-height: calc(100vh - 45px);
|
||||
max-height: calc(100svh - 45px);
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 5px;
|
||||
border: 1px solid var(--grey30);
|
||||
}
|
||||
|
||||
#select_chat_popup {
|
||||
align-items: start;
|
||||
height: min-content;
|
||||
align-content: start;
|
||||
max-width: unset;
|
||||
}
|
||||
|
||||
#top-settings-holder,
|
||||
#top-bar {
|
||||
position: fixed;
|
||||
padding-top: 8px;
|
||||
width: 100vw;
|
||||
width: 100svw;
|
||||
}
|
||||
|
||||
#bg1,
|
||||
#bg_custom {
|
||||
height: 100vh !important;
|
||||
height: 100svh !important;
|
||||
width: 100vw !important;
|
||||
width: 100svw !important;
|
||||
background-position: center;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#sheld,
|
||||
#character_popup,
|
||||
.drawer-content
|
||||
|
||||
/* ,
|
||||
#world_popup */
|
||||
{
|
||||
max-height: calc(100vh - 40px);
|
||||
max-height: calc(100svh - 40px);
|
||||
width: 100% !important;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
left: 0 !important;
|
||||
resize: none !important;
|
||||
top: 40px;
|
||||
}
|
||||
|
||||
.wi-settings {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#character_popup,
|
||||
#world_popup {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#character_popup,
|
||||
#send_form {
|
||||
border: 1px solid var(--grey30);
|
||||
backdrop-filter: blur(calc(var(--SmartThemeBlurStrength) * 2));
|
||||
max-width: 100dvw;
|
||||
}
|
||||
|
||||
#chat {
|
||||
border-left: 1px solid var(--grey30);
|
||||
border-right: 1px solid var(--grey30);
|
||||
border-bottom: 1px solid var(--grey30);
|
||||
align-items: start;
|
||||
align-content: start;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden
|
||||
}
|
||||
|
||||
.mes_buttons {
|
||||
font-size: calc(var(--mainFontSize)*1.2);
|
||||
}
|
||||
|
||||
.drag-grabber,
|
||||
.pull-tab {
|
||||
display: none !important;
|
||||
|
||||
}
|
||||
|
||||
#showRawPrompt,
|
||||
#groupCurrentMemberPopoutButton {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#right-nav-panel,
|
||||
#left-nav-panel,
|
||||
#floatingPrompt,
|
||||
#cfgConfig {
|
||||
height: calc(100vh - 45px);
|
||||
height: calc(100svh - 45px);
|
||||
min-width: 100% !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
overflow-y: hidden;
|
||||
border-left: 1px solid var(--grey30);
|
||||
border-right: 1px solid var(--grey30);
|
||||
border-bottom: 1px solid var(--grey30);
|
||||
border-radius: 0 0 20px 20px;
|
||||
top: 40px !important;
|
||||
left: 0 !important;
|
||||
backdrop-filter: blur(calc(var(--SmartThemeBlurStrength) * 2));
|
||||
}
|
||||
|
||||
#floatingPrompt,
|
||||
#cfgConfig {
|
||||
height: min-content;
|
||||
}
|
||||
|
||||
#right-nav-panel h4 {
|
||||
margin: 5px auto;
|
||||
}
|
||||
|
||||
#result_info {
|
||||
font-size: calc(var(--mainFontSize) - .1rem);
|
||||
}
|
||||
|
||||
/* .avatar_div {
|
||||
margin-top: 5px;
|
||||
} */
|
||||
|
||||
#character_popup {
|
||||
width: 100%;
|
||||
border-radius: 0 0 20px 20px;
|
||||
margin-top: 0px;
|
||||
height: calc(100% - 40px);
|
||||
}
|
||||
|
||||
.drawer25pWidth {
|
||||
flex-basis: max(calc(100% / 4 - 10px), 190px);
|
||||
}
|
||||
|
||||
.drawer33pWidth {
|
||||
flex-basis: max(calc(100% / 3 - 10px), 190px);
|
||||
}
|
||||
|
||||
.expression-holder {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body.waifuMode #sheld {
|
||||
height: 40vh;
|
||||
height: 40svh;
|
||||
top: 60vh;
|
||||
top: 60svh;
|
||||
bottom: 0 !important;
|
||||
}
|
||||
|
||||
body.waifuMode .expression-holder {
|
||||
/*display: inline;*/
|
||||
|
||||
max-width: 100vw;
|
||||
height: 100vh;
|
||||
width: max-content;
|
||||
margin: 0 auto;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
filter: drop-shadow(2px 2px 2px #51515199);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
body.waifuMode img.expression {
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
body.waifuMode .zoomed_avatar {
|
||||
width: fit-content;
|
||||
max-height: calc(60vh - 60px);
|
||||
max-height: calc(60svh - 60px);
|
||||
max-width: 90vw;
|
||||
max-width: 90svw;
|
||||
}
|
||||
|
||||
.scrollableInner {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
max-height: calc(100vh - 90px);
|
||||
max-height: calc(100svh - 90px);
|
||||
}
|
||||
|
||||
.horde_multiple_hint {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#bg_menu_content {
|
||||
width: unset;
|
||||
}
|
||||
}
|
||||
|
||||
/*landscape mode phones and ipads*/
|
||||
@media screen and (max-width: 1000px) and (orientation: landscape) {
|
||||
body.waifuMode img.expression {
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.tag.excluded:after {
|
||||
top: unset;
|
||||
bottom: unset;
|
||||
}
|
||||
|
||||
body:not(.waifuMode) .zoomed_avatar {
|
||||
|
||||
width: fit-content;
|
||||
max-height: calc(60vh - 60px);
|
||||
max-height: calc(60svh - 60px);
|
||||
max-width: 90vw;
|
||||
max-width: 90svw;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*portrait mode phones*/
|
||||
@media screen and (max-width: 450px) {
|
||||
|
||||
body:not(.waifuMode) .zoomed_avatar {
|
||||
min-width: 100px;
|
||||
min-height: 100px;
|
||||
max-height: 50vh;
|
||||
max-width: 50vh;
|
||||
width: 50vw;
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
filter: drop-shadow(2px 2px 2px #51515199);
|
||||
z-index: 30;
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 auto;
|
||||
top: 50px;
|
||||
aspect-ratio: 2 / 3;
|
||||
}
|
||||
|
||||
.drawer25pWidth {
|
||||
flex-basis: max(calc(100% / 2 - 10px), 180px);
|
||||
}
|
||||
|
||||
.drawer33pWidth {
|
||||
flex-basis: max(calc(100% / 2 - 10px), 180px);
|
||||
}
|
||||
|
||||
.BGSampleTitle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tag.excluded:after {
|
||||
top: unset;
|
||||
bottom: unset;
|
||||
}
|
||||
}
|
||||
|
||||
/*iOS specific*/
|
||||
@supports (-webkit-touch-callout: none) {
|
||||
body {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#top-bar {
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
#sheld {
|
||||
margin: unset;
|
||||
padding: unset;
|
||||
width: unset;
|
||||
height: unset;
|
||||
min-width: unset;
|
||||
max-width: unset;
|
||||
min-height: unset;
|
||||
max-height: unset;
|
||||
width: 100vw;
|
||||
width: 100svw;
|
||||
height: calc(100vh - 40px);
|
||||
height: calc(100svh - 40px);
|
||||
padding-right: max(env(safe-area-inset-right), 0px);
|
||||
padding-left: max(env(safe-area-inset-left), 0px);
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
body.PWA #sheld {
|
||||
padding-right: max(env(safe-area-inset-right), 2px);
|
||||
padding-left: max(env(safe-area-inset-left), 2px);
|
||||
padding-bottom: max(env(safe-area-inset-bottom), 15px);
|
||||
|
||||
}
|
||||
|
||||
#character_popup,
|
||||
#world_popup,
|
||||
#left-nav-panel,
|
||||
#right-nav-panel,
|
||||
.drawer-content {
|
||||
width: unset;
|
||||
height: unset;
|
||||
min-width: unset;
|
||||
max-width: unset;
|
||||
min-height: unset;
|
||||
max-height: unset;
|
||||
backdrop-filter: blur(calc(var(--SmartThemeBlurStrength) * 2));
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
margin: 0 auto;
|
||||
height: calc(100vh - 70px);
|
||||
height: calc(100svh - 70px);
|
||||
width: calc(100% - 5px);
|
||||
max-height: calc(100vh - 70px);
|
||||
max-height: calc(100svh - 70px);
|
||||
max-width: calc(100% - 5px);
|
||||
|
||||
}
|
||||
|
||||
#character_popup,
|
||||
#world_popup,
|
||||
.drawer-content {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.scrollableInner {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#horde_model {
|
||||
height: unset;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,227 @@
|
|||
/* GROUP CHATS */
|
||||
|
||||
.group_pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#rm_group_chats_block .tag.filterByGroups {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#rm_button_group_chats h2 {
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
color: rgb(188, 193, 200, 1);
|
||||
border: 1px solid #333;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
padding: 6px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#rm_group_chats_block {
|
||||
display: none;
|
||||
align-items: flex-start;
|
||||
padding: 0 5px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#rm_group_chats_block h3,
|
||||
#rm_group_chats_block h5 {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#rm_group_buttons>div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#rm_group_buttons .checkbox {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#rm_group_buttons .checkbox h4 {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#rm_group_buttons>input {
|
||||
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#rm_group_buttons>input:disabled {
|
||||
filter: brightness(0.3);
|
||||
cursor: unset;
|
||||
}
|
||||
|
||||
#rm_group_members,
|
||||
#rm_group_add_members {
|
||||
margin-top: 0.25rem;
|
||||
margin-bottom: 0.5rem;
|
||||
border: 1px solid grey;
|
||||
border-radius: 10px;
|
||||
background-color: var(--black30a);
|
||||
}
|
||||
|
||||
#rm_group_buttons_expander {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#rm_group_delete {
|
||||
color: rgb(190, 0, 0);
|
||||
}
|
||||
|
||||
#rm_group_members:empty {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#rm_group_members:empty::before {
|
||||
content: 'Group is empty';
|
||||
|
||||
font-weight: bolder;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
#rm_group_add_members:empty {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#rm_group_add_members_header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
column-gap: 10px;
|
||||
}
|
||||
|
||||
#rm_group_add_members_header input {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#rm_group_add_members:empty::before {
|
||||
content: 'No characters available';
|
||||
|
||||
font-weight: bolder;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.group_member_icon {
|
||||
display: flex;
|
||||
column-gap: 10px;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.group_member {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.group_member .group_member_name {
|
||||
flex-grow: 1;
|
||||
margin-left: 10px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: calc(100% - 110px);
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.group_member_icon .flex-container {
|
||||
gap: 0px;
|
||||
}
|
||||
|
||||
#rm_group_members .right_menu_button,
|
||||
#rm_group_add_members .right_menu_button {
|
||||
padding: 0px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#rm_group_members .right_menu_button[data-action="speak"],
|
||||
#rm_group_members .group_member:not(.disabled) .right_menu_button[data-action="disable"] {
|
||||
opacity: 0.4;
|
||||
filter: brightness(0.5);
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
/* #rm_group_members .right_menu_button[data-action="speak"]:hover, */
|
||||
#rm_group_members .group_member:not(.disabled) .right_menu_button[data-action="disable"]:hover {
|
||||
opacity: inherit;
|
||||
filter: drop-shadow(0px 0px 5px rgb(243, 166, 65));
|
||||
}
|
||||
|
||||
#rm_group_members .group_member.disabled .right_menu_button[data-action="enable"] {
|
||||
filter: drop-shadow(0px 0px 5px rgb(243, 166, 65));
|
||||
}
|
||||
|
||||
|
||||
#rm_group_members .right_menu_button[data-action="speak"]:hover {
|
||||
opacity: inherit;
|
||||
filter: drop-shadow(0px 0px 5px rgb(153, 255, 153));
|
||||
}
|
||||
|
||||
/* Rules for icon display */
|
||||
#rm_group_add_members .right_menu_button:not([data-action="add"], [data-action="view"]),
|
||||
#rm_group_members .right_menu_button[data-action="add"],
|
||||
#rm_group_members .group_member.disabled .right_menu_button[data-action="disable"],
|
||||
#rm_group_members .group_member:not(.disabled) .right_menu_button[data-action="enable"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.group_select {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 5px;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.group_select:hover {
|
||||
background-color: var(--white30a);
|
||||
}
|
||||
|
||||
.group_select .avatar {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
.group_select .group_icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.group_select .group_fav_icon {
|
||||
filter: drop-shadow(0px 0px 1px black);
|
||||
color: #c5b457;
|
||||
font-size: 12px;
|
||||
order: -1;
|
||||
margin-left: -18px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.group_member .avatar {
|
||||
flex-shrink: 0;
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/* Customize the Select2 container */
|
||||
.select2-container {
|
||||
color: var(--SmartThemeBodyColor);
|
||||
}
|
||||
|
||||
/* Customize the dropdown */
|
||||
.select2-dropdown {
|
||||
background-color: var(--SmartThemeBlurTintColor);
|
||||
border: 1px solid var(--white30a) !important;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 5px black;
|
||||
text-shadow: 0px 0px calc(var(--shadowWidth) * 1px) var(--SmartThemeShadowColor);
|
||||
backdrop-filter: blur(calc(var(--SmartThemeBlurStrength)*2));
|
||||
color: var(--SmartThemeBodyColor);
|
||||
z-index: 40000;
|
||||
}
|
||||
|
||||
.select2-selection__clear {
|
||||
color: var(--SmartThemeBodyColor);
|
||||
}
|
||||
|
||||
.select2-container .select2-selection--multiple .select2-selection__choice__remove {
|
||||
padding: revert;
|
||||
border-right: 1px solid var(--white30a);
|
||||
font-size: 1.1em;
|
||||
|
||||
}
|
||||
|
||||
.select2-container .select2-selection--multiple .select2-selection__choice__display {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
/* Customize the search input */
|
||||
.select2-search__field {
|
||||
background-color: var(--black30a);
|
||||
color: var(--SmartThemeBodyColor);
|
||||
border: 1px solid var(--white30a);
|
||||
border-radius: 7px;
|
||||
font-family: "Noto Sans", "Noto Color Emoji", sans-serif;
|
||||
padding: 3px 5px;
|
||||
}
|
||||
|
||||
/* Customize the selected option */
|
||||
.select2-selection--single {
|
||||
border: 1px solid var(--SmartThemeShadowColor);
|
||||
border-radius: 4px;
|
||||
background-color: var(--SmartThemeBlurTintColor);
|
||||
}
|
||||
|
||||
/* Customize the selected option text */
|
||||
.select2-selection__rendered {
|
||||
color: var(--SmartThemeBodyColor);
|
||||
}
|
||||
|
||||
/* Customize the option list item */
|
||||
.select2-results__option {
|
||||
color: var(--SmartThemeBodyColor);
|
||||
background-color: var(--SmartThemeBodyColor);
|
||||
}
|
||||
|
||||
.select2-container .select2-selection--multiple {
|
||||
background-color: var(--black30a);
|
||||
color: var(--SmartThemeBodyColor);
|
||||
border: 1px solid var(--white30a);
|
||||
border-radius: 7px;
|
||||
font-family: "Noto Sans", "Noto Color Emoji", sans-serif;
|
||||
padding: 3px 5px;
|
||||
}
|
||||
|
||||
.select2-container.select2-container--focus .select2-selection--multiple {
|
||||
border: 1px solid var(--white30a);
|
||||
}
|
||||
|
||||
.select2-container .select2-selection--multiple .select2-selection__choice {
|
||||
border-radius: 5px;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
box-sizing: border-box;
|
||||
color: var(--SmartThemeBodyColor);
|
||||
background-color: var(--black30a);
|
||||
border-color: var(--white30a);
|
||||
font-size: calc(var(--mainFontSize) - 5%);
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
.select2-results .select2-results__option--selectable {
|
||||
background-color: unset;
|
||||
color: var(--SmartThemeBodyColor);
|
||||
opacity: 0.5;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Customize the hovered option list item */
|
||||
.select2-results .select2-results__option--highlighted.select2-results__option--selectable {
|
||||
color: var(--SmartThemeBodyColor);
|
||||
background-color: unset;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Customize the option list item */
|
||||
.select2-results__option {
|
||||
padding-left: 30px;
|
||||
/* Add some padding to make room for the checkbox */
|
||||
}
|
||||
|
||||
/* Add the custom checkbox */
|
||||
.select2-results__option:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
top: 50%;
|
||||
margin-top: -7px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border: 1px solid var(--white30a);
|
||||
background-color: var(--SmartThemeBlurTintColor);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.select2-container .select2-selection--multiple .select2-selection__choice__remove {
|
||||
color: var(--SmartThemeBodyColor);
|
||||
}
|
||||
|
||||
/* Add the custom checkbox checkmark */
|
||||
.select2-results__option--selected.select2-results__option:before {
|
||||
content: '\2713';
|
||||
font-weight: bold;
|
||||
color: var(--SmartThemeBodyColor);
|
||||
background-color: var(--SmartThemeBlurTintColor);
|
||||
text-align: center;
|
||||
line-height: 14px;
|
||||
}
|
|
@ -0,0 +1,419 @@
|
|||
.text_warning {
|
||||
color: rgb(220 173 16);
|
||||
}
|
||||
|
||||
.text_danger {
|
||||
color: var(--fullred);
|
||||
}
|
||||
|
||||
.m-t-1 {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.m-t-2 {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.m-t-3 {
|
||||
margin-top: 3em;
|
||||
}
|
||||
|
||||
.m-t-4 {
|
||||
margin-top: 4em;
|
||||
}
|
||||
|
||||
.m-t-5 {
|
||||
margin-top: 5em;
|
||||
}
|
||||
|
||||
.m-b-1 {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.m-b-2 {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.m-b-3 {
|
||||
margin-bottom: 3em;
|
||||
}
|
||||
|
||||
.m-b-4 {
|
||||
margin-bottom: 4em;
|
||||
}
|
||||
|
||||
.m-b-5 {
|
||||
margin-bottom: 5em;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.margin-bot-10px,
|
||||
.marginBot10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.marginTop10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.marginBot5 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.marginTop5 {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.marginTopBot5 {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.margin5 {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.overflowYAuto {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.heightMinContent {
|
||||
height: min-content;
|
||||
}
|
||||
|
||||
.justifySpaceBetween {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.alignitemsflexstart {
|
||||
align-items: flex-start !important;
|
||||
}
|
||||
|
||||
.alignItemsFlexEnd {
|
||||
align-items: flex-end !important;
|
||||
}
|
||||
|
||||
.alignSelfStart {
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
.gap5px {
|
||||
gap: 5px !important;
|
||||
}
|
||||
|
||||
.gap10px {
|
||||
gap: 10px !important;
|
||||
}
|
||||
|
||||
.wide10pMinFit {
|
||||
width: 10%;
|
||||
min-width: fit-content;
|
||||
}
|
||||
|
||||
.wide100pLess70px {
|
||||
width: calc(100% - 70px);
|
||||
}
|
||||
|
||||
.wideMax100px {
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
.widthUnset {
|
||||
width: unset;
|
||||
}
|
||||
|
||||
.no-border {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.no-shadow {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.height100pSpaceEvenly {
|
||||
align-content: space-evenly;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.height32px {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.TxtLrgBoldCenter {
|
||||
text-align: center;
|
||||
font-size: large;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.margin-right-10px {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
.success {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.failure {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.optional {
|
||||
color: lightgray;
|
||||
}
|
||||
|
||||
.monospace {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.expander {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.redOverlayGlow {
|
||||
color: #800;
|
||||
opacity: 0.8 !important;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
.width100p {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.flexNoGap {
|
||||
gap: unset !important;
|
||||
}
|
||||
|
||||
.flexGrow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.flexnowrap {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.alignitemscenter {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.alignitemsstart {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.overflow-hidden {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.maxWidth200px {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.alignContentFlexStart {
|
||||
align-content: flex-start;
|
||||
}
|
||||
|
||||
.overflowHidden {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.padding5 {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.padding10 {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.margin0 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.margin0auto {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.margin-r5 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.flex1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.flex2 {
|
||||
flex: 2 !important;
|
||||
}
|
||||
|
||||
.flexFlowColumn {
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
.wideMinContent {
|
||||
width: min-content;
|
||||
}
|
||||
|
||||
.flexWide50p {
|
||||
flex: 50%;
|
||||
}
|
||||
|
||||
.wide50p {
|
||||
width: 50% !important;
|
||||
}
|
||||
|
||||
.wide25p {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.wide30p {
|
||||
width: 30% !important;
|
||||
}
|
||||
|
||||
.justifyLeft {
|
||||
text-align: start;
|
||||
justify-content: left;
|
||||
margin-left: unset;
|
||||
}
|
||||
|
||||
.justifyCenter {
|
||||
justify-content: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.justifyContentSpaceAround {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.justifyContentFlexStart {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.justifyContentFlexEnd {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.spaceEvenly {
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.spaceBetween {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.widthNatural {
|
||||
width: unset !important;
|
||||
min-width: unset !important;
|
||||
max-width: unset !important;
|
||||
}
|
||||
|
||||
.widthFreeExpand {
|
||||
width: -webkit-fill-available;
|
||||
width: -moz-available;
|
||||
}
|
||||
|
||||
.wide100p {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wide50p {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.wide50px {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.indent20p {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
/*used to fix smallness of certain FontAwesome glyph which break button squareness*/
|
||||
/*currently used on: CharList Import*/
|
||||
|
||||
.faSmallFontSquareFix {
|
||||
font-size: calc(var(--mainFontSize) *1.25);
|
||||
width: calc(var(--mainFontSize) *1.95);
|
||||
}
|
||||
|
||||
.textarea_compact {
|
||||
font-size: calc(var(--mainFontSize) * 0.9);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.katex-html {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hoverglow:hover {
|
||||
opacity: 1 !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.debug-red {
|
||||
border: 1px solid red !important;
|
||||
}
|
||||
|
||||
.debug-yellow {
|
||||
border: 1px solid yellow !important;
|
||||
}
|
||||
|
||||
.debug-green {
|
||||
border: 1px solid green !important;
|
||||
}
|
||||
|
||||
.debug-blue {
|
||||
border: 1px solid blue !important;
|
||||
}
|
||||
|
||||
.debug-purple {
|
||||
border: 1px solid purple !important;
|
||||
}
|
||||
|
||||
.fontsize80p {
|
||||
font-size: calc(var(--mainFontSize) * 0.8) !important;
|
||||
}
|
||||
|
||||
.fontsize60p {
|
||||
font-size: calc(var(--mainFontSize) * 0.6) !important;
|
||||
}
|
||||
|
||||
.paddingTopBot5 {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.paddingLeftRight5 {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.heightFitContent {
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
.widthFitContent {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.flexGap5 {
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.flexGap10 {
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.opacity1 {
|
||||
opacity: 1 !important;
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
#tags_div {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.tag_controls {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 5px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tag_view_item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: baseline;
|
||||
gap: 10px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.tag_view_name {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.tag_view_counter {
|
||||
text-align: right;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.tag_delete {
|
||||
padding-right: 0;
|
||||
color: var(--SmartThemeBodyColor) !important;
|
||||
}
|
||||
|
||||
.tag {
|
||||
border-radius: 5px;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
box-sizing: border-box;
|
||||
color: var(--SmartThemeBodyColor);
|
||||
background-color: var(--black30a);
|
||||
border-color: var(--white50a);
|
||||
padding: 0.1rem 0.2rem;
|
||||
font-size: calc(var(--mainFontSize) - 5%);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
gap: 10px;
|
||||
width: fit-content;
|
||||
min-width: 0;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
.rm_tag_filter .tag:not(.actionable) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tag.actionable {
|
||||
border-radius: 50%;
|
||||
aspect-ratio: 1 / 1;
|
||||
min-height: calc(var(--mainFontSize) * 2);
|
||||
min-width: calc(var(--mainFontSize) * 2);
|
||||
font-size: calc(var(--mainFontSize) * 1);
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tagListHint {
|
||||
align-self: center;
|
||||
display: flex;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.tag_remove {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tags {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
gap: 0.2rem;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
#tagList.tags {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
#tagList .tag {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.tags.tags_inline {
|
||||
opacity: 0.6;
|
||||
column-gap: 0.2rem;
|
||||
row-gap: 0.2rem;
|
||||
justify-content: flex-start;
|
||||
max-height: 66%;
|
||||
overflow: hidden;
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
.tag_name {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tags_inline .tag {
|
||||
font-size: calc(var(--mainFontSize) - 15%);
|
||||
padding: 0 0.15rem;
|
||||
}
|
||||
|
||||
.rm_tag_controls {
|
||||
display: flex;
|
||||
column-gap: 10px;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.rm_tag_filter .tag {
|
||||
cursor: pointer;
|
||||
opacity: 0.6;
|
||||
filter: brightness(0.8);
|
||||
}
|
||||
|
||||
.tags_view,
|
||||
.open_alternate_greetings {
|
||||
margin: 0;
|
||||
aspect-ratio: 1 / 1;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.tag.selected {
|
||||
opacity: 1 !important;
|
||||
filter: none !important;
|
||||
}
|
||||
|
||||
.tag.excluded {
|
||||
opacity: 1 !important;
|
||||
filter: saturate(0.4) !important;
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.tag.excluded:after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
content: "\d7";
|
||||
font-size: calc(var(--mainFontSize) *3);
|
||||
color: red;
|
||||
line-height: calc(var(--mainFontSize)*1.3);
|
||||
text-align: center;
|
||||
text-shadow: 1px 1px 0px black,
|
||||
-1px -1px 0px black,
|
||||
-1px 1px 0px black,
|
||||
1px -1px 0px black;
|
||||
opacity: 1;
|
||||
}
|
|
@ -0,0 +1,367 @@
|
|||
body.tts .mes[is_user="true"] .mes_narrate,
|
||||
body.tts .mes[is_system="true"] .mes_narrate {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body.sd .sd_message_gen,
|
||||
body.translate .mes_translate,
|
||||
body.tts .mes_narrate {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
body.no-hotswap .hotswap {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
body.no-timer .mes_timer {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
body.no-timestamps .timestamp,
|
||||
body.no-mesIDDisplay .mesIDDisplay,
|
||||
body.no-modelIcons .icon-svg {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/*char list grid mode*/
|
||||
|
||||
body.charListGrid #rm_print_characters_block {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
align-content: flex-start;
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .character_select {
|
||||
width: 30%;
|
||||
align-items: flex-start;
|
||||
height: min-content;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .character_select .ch_name,
|
||||
body.charListGrid #rm_print_characters_block .group_select .ch_name {
|
||||
width: 100%;
|
||||
max-width: 100px;
|
||||
text-align: center;
|
||||
font-size: calc(var(--mainFontSize) * .8);
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .character_select .character_name_block {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .character_select .character_select_container {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .group_select {
|
||||
width: 30%;
|
||||
height: min-content;
|
||||
align-items: center !important;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .group_select .group_name_block {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body.charListGrid #rm_print_characters_block .ch_description,
|
||||
body.charListGrid #rm_print_characters_block .tags_inline,
|
||||
body.charListGrid #rm_print_characters_block .character_version,
|
||||
body.charListGrid #rm_print_characters_block .ch_avatar_url {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*big avatars mode page-wide changes*/
|
||||
|
||||
body.big-avatars .character_select .avatar {
|
||||
flex: unset;
|
||||
}
|
||||
|
||||
body:not(.big-avatars) .avatar {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
body.big-avatars .avatar {
|
||||
width: 60px;
|
||||
height: 90px;
|
||||
/* width: unset; */
|
||||
border-style: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
/* align-self: unset; */
|
||||
overflow: visible;
|
||||
border-radius: 10px;
|
||||
flex: 1
|
||||
}
|
||||
|
||||
body.big-avatars #user_avatar_block .avatar,
|
||||
body.big-avatars #user_avatar_block .avatar_upload {
|
||||
height: 90px;
|
||||
width: 60px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
body.big-avatars #user_avatar_block .avatar img {
|
||||
height: 90px;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
body.big-avatars .avatar img {
|
||||
width: 60px;
|
||||
height: 90px;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
border: 1px solid var(--black30a);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
body:not(.big-avatars) .avatar_collage {
|
||||
min-width: 50px;
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
body:not(.big-avatars) .avatar_collage img {
|
||||
border-radius: 0% !important;
|
||||
}
|
||||
|
||||
body.big-avatars .avatar_collage {
|
||||
min-width: 60px;
|
||||
max-width: 60px;
|
||||
aspect-ratio: 2 / 3;
|
||||
}
|
||||
|
||||
body.big-avatars .ch_description {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
white-space: normal;
|
||||
text-overflow: unset;
|
||||
}
|
||||
|
||||
/* border radius for big avatars collages */
|
||||
|
||||
body.big-avatars .collage_2 .img_1 {
|
||||
border-radius: 10px 0 0 10px !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_2 .img_2 {
|
||||
border-radius: 0 10px 10px 0 !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_3 .img_1 {
|
||||
border-radius: 10px 0 0 0 !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_3 .img_2 {
|
||||
border-radius: 0 10px 0 0 !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_3 .img_3 {
|
||||
border-radius: 0 0 10px 10px !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_4 .img_1 {
|
||||
border-radius: 10px 0 0 0 !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_4 .img_2 {
|
||||
border-radius: 0 10px 0 0 !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_4 .img_3 {
|
||||
border-radius: 0 0 0 10px !important;
|
||||
}
|
||||
|
||||
body.big-avatars .collage_4 .img_4 {
|
||||
border-radius: 0 0 10px 0 !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*bubble chat style*/
|
||||
|
||||
body.bubblechat .mes {
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
background-color: var(--SmartThemeBotMesBlurTintColor);
|
||||
margin-bottom: 5px;
|
||||
border: 1px solid var(--white30a);
|
||||
}
|
||||
|
||||
body.bubblechat .mes[is_user="true"] {
|
||||
background-color: var(--SmartThemeUserMesBlurTintColor);
|
||||
}
|
||||
|
||||
|
||||
/* Document Style */
|
||||
|
||||
body.documentstyle #chat .mes:not(.last_mes) {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
body.documentstyle .last_mes {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
body.documentstyle #chat .mes .mes_text {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body.documentstyle #chat .mes .mes_block {
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
body.documentstyle #chat .mes .mes_text {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
body.documentstyle #chat .last_mes .mes_text {
|
||||
margin-left: 20px;
|
||||
min-height: 70px;
|
||||
}
|
||||
|
||||
body.documentstyle #chat .last_mes:has(> .del_checkbox[style*="display: block"]) .mes_text {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
body.documentstyle #chat .last_mes .swipe_left {
|
||||
left: 5px;
|
||||
}
|
||||
|
||||
body.documentstyle #chat .mes .mesAvatarWrapper,
|
||||
body.documentstyle #chat .mes .mes_block .ch_name .name_text,
|
||||
body.documentstyle #chat .mes .mes_block .ch_name .timestamp,
|
||||
body.documentstyle .mes:not(.last_mes) .ch_name .mes_buttons {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/*FastUI blur removal*/
|
||||
|
||||
body.no-blur * {
|
||||
backdrop-filter: unset !important;
|
||||
}
|
||||
|
||||
body.no-blur #send_form.no-connection {
|
||||
background-color: rgba(100, 0, 0, 0.9) !important;
|
||||
}
|
||||
|
||||
body.no-blur #bg1,
|
||||
body.no-blur #bg_custom {
|
||||
filter: unset;
|
||||
|
||||
}
|
||||
|
||||
body:not(.bubblechat).no-blur #chat,
|
||||
body.no-blur #top-bar,
|
||||
body.no-blur #send_form {
|
||||
background-color: var(--SmartThemeBlurTintColor) !important;
|
||||
}
|
||||
|
||||
body.no-blur #options,
|
||||
body.no-blur .ui-widget-content,
|
||||
body.no-blur #floatingPrompt,
|
||||
body.no-blur #extensionsMenu,
|
||||
body.no-blur .list-group,
|
||||
body.no-blur #character_popup,
|
||||
body.no-blur #world_popup,
|
||||
body.no-blur #dialogue_popup,
|
||||
body.no-blur #select_chat_popup,
|
||||
body.no-blur .drawer-content,
|
||||
body.no-blur .select2-results__options {
|
||||
background-color: black !important;
|
||||
}
|
||||
|
||||
/* wAIfu mode*/
|
||||
|
||||
body.waifuMode #top-bar {
|
||||
border-radius: 0 0 20px 20px;
|
||||
border: 1px solid var(--grey30a);
|
||||
}
|
||||
|
||||
body.waifuMode #sheld {
|
||||
height: 40vh;
|
||||
height: 40svh;
|
||||
top: calc(100% - 40vh);
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
body.waifuMode #chat {
|
||||
border-top: 1px solid var(--grey30a);
|
||||
border-radius: 20px 20px 0 0;
|
||||
}
|
||||
|
||||
body.waifuMode #expression-wrapper {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
body.waifuMode .expression-holder {
|
||||
max-height: 90vh;
|
||||
max-width: 90vw;
|
||||
height: 90vh;
|
||||
width: fit-content;
|
||||
bottom: 0;
|
||||
filter: drop-shadow(2px 2px 2px #51515199);
|
||||
z-index: 2;
|
||||
margin: 0 auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
body.waifuMode .zoomed_avatar {
|
||||
min-width: 100px;
|
||||
min-height: 100px;
|
||||
max-height: 90vh;
|
||||
max-width: 90vh;
|
||||
width: calc((100vw - var(--sheldWidth)) /2);
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
filter: drop-shadow(2px 2px 2px #51515199);
|
||||
z-index: 29;
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 auto;
|
||||
top: 50px;
|
||||
aspect-ratio: 2 / 3;
|
||||
}
|
||||
|
||||
/* movingUI*/
|
||||
|
||||
body.movingUI .drag-grabber {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
body.movingUI #sheld,
|
||||
body.movingUI .drawer-content,
|
||||
body.movingUI #expression-holder,
|
||||
body.movingUI .zoomed_avatar,
|
||||
body.movingUI #floatingPrompt,
|
||||
body.movingUI #groupMemberListPopout {
|
||||
resize: both;
|
||||
}
|
||||
|
||||
#expression-image.default,
|
||||
#expression-holder:has(.default) {
|
||||
height: 120px;
|
||||
margin-top: 0;
|
||||
top: 50px;
|
||||
}
|
||||
|
||||
/*No Text Shadows Mode*/
|
||||
|
||||
body.noShadows * {
|
||||
text-shadow: none !important;
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
.world_info_select_block {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: baseline;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.budget_cap_note {
|
||||
flex-basis: 100%;
|
||||
line-height: 0.1;
|
||||
}
|
||||
|
||||
#world_popup {
|
||||
min-height: 100px;
|
||||
min-width: 100px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
flex-direction: column;
|
||||
z-index: 3010;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.WIEntryContentAndMemo {
|
||||
width: 100% !important;
|
||||
flex-wrap: nowrap !important;
|
||||
}
|
||||
|
||||
.WIEntryContentAndMemo .world_entry_thin_controls {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#world_popup_bottom_holder {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#world_popup_bottom_holder div {
|
||||
width: fit-content;
|
||||
user-select: none;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.world_popup_logo_block {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#world_popup_header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#world_popup_header h3 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#form_rename_world {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
opacity: 0.8;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
#form_rename_world input[type="submit"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#form_world_import {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#world_popup_header h5 {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.world_popup_expander {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#world_popup_entries_list {
|
||||
flex-grow: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#world_popup_entries_list:empty {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#world_popup_entries_list:empty::before {
|
||||
content: 'No entries exist. Try creating one!';
|
||||
font-size: calc(var(--mainFontSize) + .5rem);
|
||||
font-weight: bolder;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.world_entry_form_control {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.world_entry_thin_controls {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
/* .world_entry_thin_controls>div {
|
||||
flex: 1;
|
||||
} */
|
||||
|
||||
.world_entry_form_control label h4 {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.world_entry_form_control label h5 {
|
||||
margin-top: 3px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.world_entry_form_control textarea {
|
||||
height: auto;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
.delete_entry_button {
|
||||
height: min-content;
|
||||
}
|
||||
|
||||
.world_entry_form_control.world_entry_form_horizontal {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.world_entry_form_control input[type=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.world_entry_form_horizontal h5 {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.world_entry_form_control .checkbox {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
column-gap: 10px;
|
||||
}
|
||||
|
||||
.world_entry_form_control .checkbox h4 {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.world_entry_form_radios label {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.world_entry_form_radios h4 {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#world_popup h5 {
|
||||
color: var(--grey70);
|
||||
}
|
||||
|
||||
/* possible place for WI Entry header styling */
|
||||
/* .world_entry_form .inline-drawer-header {
|
||||
background-color: var(--SmartThemeShadowColor);
|
||||
} */
|
|
@ -48,7 +48,19 @@
|
|||
<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>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="css/st-tailwind.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/tags.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/rm-groups.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/group-avatars.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/toggle-dependent.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/world-info.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/extensions-panel.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/select2-overrides.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/mobile-styles.css">
|
||||
|
||||
<link rel="stylesheet" href="css/bg_load.css">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<script>
|
||||
|
@ -131,7 +143,7 @@
|
|||
<div class="checked fa-solid fa-lock "></div>
|
||||
</label>
|
||||
</div>
|
||||
<div data-i18n="clickslidertips" class="toggle-description flex-container justifyLeft wide100p editable-slider-notification">
|
||||
<div data-i18n="clickslidertips" class="toggle-description wide100p editable-slider-notification">
|
||||
Click slider numbers to input manually.
|
||||
</div>
|
||||
<div class="scrollableInner">
|
||||
|
@ -151,8 +163,8 @@
|
|||
</select>
|
||||
<i data-preset-manager-update="kobold" class="menu_button fa-solid fa-save" title="Update current preset" data-i18n="[title]Update current preset"></i>
|
||||
<i data-preset-manager-new="kobold" class="menu_button fa-solid fa-plus" title="Create new preset" data-i18n="[title]Create new preset"></i>
|
||||
<i data-preset-manager-import="kobold" class="menu_button fa-solid fa-upload" title="Import preset" data-i18n="[title]Import preset"></i>
|
||||
<i data-preset-manager-export="kobold" class="menu_button fa-solid fa-download" title="Export preset" data-i18n="[title]Export preset"></i>
|
||||
<i data-preset-manager-import="kobold" class="menu_button fa-solid fa-file-import" title="Import preset" data-i18n="[title]Import preset"></i>
|
||||
<i data-preset-manager-export="kobold" class="menu_button fa-solid fa-file-export" title="Export preset" data-i18n="[title]Export preset"></i>
|
||||
<i data-preset-manager-delete="kobold" class="menu_button fa-solid fa-trash-can" title="Delete the preset" data-i18n="[title]Delete the preset"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -169,8 +181,8 @@
|
|||
</select>
|
||||
<i data-preset-manager-update="novel" class="menu_button fa-solid fa-save" title="Update current preset" data-i18n="[title]Update current preset"></i>
|
||||
<i data-preset-manager-new="novel" class="menu_button fa-solid fa-plus" title="Create new preset" data-i18n="[title]Create new preset"></i>
|
||||
<i data-preset-manager-import="novel" class="menu_button fa-solid fa-upload" title="Import preset" data-i18n="[title]Import preset"></i>
|
||||
<i data-preset-manager-export="novel" class="menu_button fa-solid fa-download" title="Export preset" data-i18n="[title]Export preset"></i>
|
||||
<i data-preset-manager-import="novel" class="menu_button fa-solid fa-file-import" title="Import preset" data-i18n="[title]Import preset"></i>
|
||||
<i data-preset-manager-export="novel" class="menu_button fa-solid fa-file-export" title="Export preset" data-i18n="[title]Export preset"></i>
|
||||
<i data-preset-manager-delete="novel" class="menu_button fa-solid fa-trash-can" title="Delete the preset" data-i18n="[title]Delete the preset"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -183,8 +195,8 @@
|
|||
</select>
|
||||
<i id="update_oai_preset" class="menu_button fa-solid fa-save" title="Update current preset" data-i18n="[title]Update current preset"></i>
|
||||
<i id="new_oai_preset" class="menu_button fa-solid fa-plus" title="Create new preset" data-i18n="[title]Create new preset"></i>
|
||||
<i title="Import preset" id="import_oai_preset" class="menu_button fa-solid fa-upload" data-i18n="[title]Import preset"></i>
|
||||
<i title="Export preset" id="export_oai_preset" class="menu_button fa-solid fa-download" data-i18n="[title]Export preset"></i>
|
||||
<i title="Import preset" id="import_oai_preset" class="menu_button fa-solid fa-file-import" data-i18n="[title]Import preset"></i>
|
||||
<i title="Export preset" id="export_oai_preset" class="menu_button fa-solid fa-file-export" data-i18n="[title]Export preset"></i>
|
||||
<i id="delete_oai_preset" class="menu_button fa-solid fa-trash-can" title="Delete the preset" data-i18n="[title]Delete the preset"></i>
|
||||
<input id="openai_preset_import_file" type="file" accept=".json,.settings" hidden />
|
||||
</div>
|
||||
|
@ -198,8 +210,8 @@
|
|||
</select>
|
||||
<i data-preset-manager-update="textgenerationwebui" class="menu_button fa-solid fa-save" title="Update current preset" data-i18n="[title]Update current preset"></i>
|
||||
<i data-preset-manager-new="textgenerationwebui" class="menu_button fa-solid fa-plus" title="Create new preset" data-i18n="[title]Create new preset"></i>
|
||||
<i data-preset-manager-import="textgenerationwebui" class="menu_button fa-solid fa-upload" title="Import preset" data-i18n="[title]Import preset"></i>
|
||||
<i data-preset-manager-export="textgenerationwebui" class="menu_button fa-solid fa-download" title="Export preset" data-i18n="[title]Export preset"></i>
|
||||
<i data-preset-manager-import="textgenerationwebui" class="menu_button fa-solid fa-file-import" title="Import preset" data-i18n="[title]Import preset"></i>
|
||||
<i data-preset-manager-export="textgenerationwebui" class="menu_button fa-solid fa-file-export" title="Export preset" data-i18n="[title]Export preset"></i>
|
||||
<i data-preset-manager-delete="textgenerationwebui" class="menu_button fa-solid fa-trash-can" title="Delete the preset" data-i18n="[title]Delete the preset"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1609,8 +1621,8 @@
|
|||
<select id="openai_logit_bias_preset">
|
||||
</select>
|
||||
<i title="New preset" id="openai_logit_bias_new_preset" class="menu_button fa-solid fa-plus" data-i18n="[title]New preset"></i>
|
||||
<i title="Import preset" id="openai_logit_bias_import_preset" class="menu_button fa-solid fa-upload" data-i18n="[title]Import preset"></i>
|
||||
<i title="Export preset" id="openai_logit_bias_export_preset" class="menu_button fa-solid fa-download" data-i18n="[title]Export preset"></i>
|
||||
<i title="Import preset" id="openai_logit_bias_import_preset" class="menu_button fa-solid fa-file-import" data-i18n="[title]Import preset"></i>
|
||||
<i title="Export preset" id="openai_logit_bias_export_preset" class="menu_button fa-solid fa-file-export" data-i18n="[title]Export preset"></i>
|
||||
<i title="Delete preset" id="openai_logit_bias_delete_preset" class="menu_button fa-solid fa-trash-can" data-i18n="[title]Delete preset"></i>
|
||||
<input id="openai_logit_bias_import_file" type="file" accept=".json" hidden />
|
||||
</div>
|
||||
|
@ -1793,22 +1805,27 @@
|
|||
<input id="use-mancer-api-checkbox" type="checkbox" />
|
||||
</label>
|
||||
</div>
|
||||
<div id="mancer-api-ui" style="display:none;">
|
||||
<h4 data-i18n="Mancer API key">Mancer API key</h4>
|
||||
<div class="flex-container">
|
||||
<input id="api_key_mancer" name="api_key_mancer" class="text_pole flex1 wide100p" maxlength="500" size="35" type="text" autocomplete="off">
|
||||
<div title="Clear your API key" data-i18n="[title]Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_mancer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex-container flexFlowColumn">
|
||||
<div id="mancer_api_subpanel" class="flex-container flexFlowColumn" style="display:none;">
|
||||
<h4 data-i18n="Mancer API key">Mancer API key</h4>
|
||||
<div class="flex-container">
|
||||
<input id="api_key_mancer" name="api_key_mancer" class="text_pole flex1 wide100p" maxlength="500" size="35" type="text" autocomplete="off">
|
||||
<div title="Clear your API key" data-i18n="[title]Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_mancer">
|
||||
</div>
|
||||
</div>
|
||||
<div data-for="api_key_mancer" class="neutral_warning" data-i18n="For privacy reasons, your API key will be hidden after you reload the page.">
|
||||
For privacy reasons, your API key will be hidden after you reload the page.
|
||||
</div>
|
||||
<div class="flex1">
|
||||
<h4 data-i18n="Mancer API url">Mancer API url</h4>
|
||||
<small>Example: https://neuro.mancer.tech/webui/MODEL/api</small>
|
||||
<input id="mancer_api_url_text" name="mancer_api_url" class="text_pole wide100p" maxlength="500" value="" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<div id="tgwebui_api_subpanel" class="flex-container flexFlowColumn">
|
||||
<div class="flex1">
|
||||
<h4 data-i18n="Blocking API url">Blocking API url</h4>
|
||||
<small>Example: http://127.0.0.1:5000/</small>
|
||||
<small>Example: http://127.0.0.1:5000/api</small>
|
||||
<input id="textgenerationwebui_api_url_text" name="textgenerationwebui_api_url" class="text_pole wide100p" maxlength="500" value="" autocomplete="off">
|
||||
</div>
|
||||
<div class="flex1">
|
||||
|
@ -2152,7 +2169,7 @@
|
|||
<small data-i18n="Input Sequence">Input Sequence</small>
|
||||
</label>
|
||||
<div>
|
||||
<textarea id="instruct_input_sequence" class="text_pole textarea_compact" maxlength="500" rows="1"></textarea>
|
||||
<textarea id="instruct_input_sequence" class="text_pole textarea_compact" maxlength="500" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex1">
|
||||
|
@ -2160,7 +2177,7 @@
|
|||
<small data-i18n="Output Sequence">Output Sequence</small>
|
||||
</label>
|
||||
<div>
|
||||
<textarea id="instruct_output_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="1"></textarea>
|
||||
<textarea id="instruct_output_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex1">
|
||||
|
@ -2168,7 +2185,7 @@
|
|||
<small data-i18n="Last Sequence">Last Sequence</small>
|
||||
</label>
|
||||
<div>
|
||||
<textarea id="instruct_last_output_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="1"></textarea>
|
||||
<textarea id="instruct_last_output_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2178,7 +2195,7 @@
|
|||
<small data-i18n="System Sequence">System Sequence</small>
|
||||
</label>
|
||||
<div>
|
||||
<textarea id="instruct_system_sequence" class="text_pole textarea_compact" maxlength="500" rows="1"></textarea>
|
||||
<textarea id="instruct_system_sequence" class="text_pole textarea_compact" maxlength="500" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex1">
|
||||
|
@ -2186,7 +2203,7 @@
|
|||
<small data-i18n="Stop Sequence">Stop Sequence</small>
|
||||
</label>
|
||||
<div>
|
||||
<textarea id="instruct_stop_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="1"></textarea>
|
||||
<textarea id="instruct_stop_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex1">
|
||||
|
@ -2194,7 +2211,7 @@
|
|||
<small data-i18n="Separator">Separator</small>
|
||||
</label>
|
||||
<div>
|
||||
<textarea id="instruct_separator_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="1"></textarea>
|
||||
<textarea id="instruct_separator_sequence" class="text_pole wide100p textarea_compact" maxlength="500" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3286,7 +3303,7 @@
|
|||
<div class="inline-drawer-content">
|
||||
<div name="Unadded Char List" class="flex-container flexFlowColumn overflowYAuto flex1">
|
||||
<div id="rm_group_add_members_header">
|
||||
<input id="rm_group_filter" class="text_pole margin0" type="search" data-i18n="[placeholder]Filter..." placeholder="Filter..." maxlength="100" />
|
||||
<input id="rm_group_filter" class="text_pole margin0" type="search" data-i18n="[placeholder]Search..." placeholder="Search..." maxlength="100" />
|
||||
</div>
|
||||
<div class="rm_tag_controls">
|
||||
<div class="tags rm_tag_filter"></div>
|
||||
|
@ -3310,7 +3327,7 @@
|
|||
<div id="charListFixedTop">
|
||||
<form id="form_character_search_form" action="javascript:void(null);">
|
||||
<div id="rm_button_create" title="Create New Character" data-i18n="[title]Create New Character" class="menu_button fa-solid fa-user-plus "></div>
|
||||
<div id="character_import_button" title="Import Character from File" data-i18n="[title]Import Character from File" class="menu_button fa-solid fa-file-arrow-up faSmallFontSquareFix"></div>
|
||||
<div id="character_import_button" title="Import Character from File" data-i18n="[title]Import Character from File" class="menu_button fa-solid fa-file-import faSmallFontSquareFix"></div>
|
||||
<div id="external_import_button" title="Import content from external URL" data-i18n="[title]Import content from external URL" class="menu_button fa-solid fa-cloud-arrow-down faSmallFontSquareFix"></div>
|
||||
<div id="rm_button_group_chats" title="Create New Chat Group" data-i18n="[title]Create New Chat Group" class="menu_button fa-solid fa-users-gear "></div>
|
||||
<input id="character_search_bar" class="text_pole width100p" type="search" data-i18n="[placeholder]Search..." placeholder="Search..." maxlength="50" />
|
||||
|
@ -3467,7 +3484,7 @@
|
|||
<div id="select_chat_popup">
|
||||
<input type="text" id="select_chat_search" placeholder="Search..." autocomplete="off">
|
||||
<div id="select_chat_import"> <!-- import chat popup header -->
|
||||
<div id="chat_import_button" class="fa-solid fa-file-arrow-up menu_button"></div>
|
||||
<div id="chat_import_button" class="fa-solid fa-file-import menu_button"></div>
|
||||
<div id="selectChatPopupHeaderText" class="TxtLrgBoldCenter">
|
||||
<span id="ChatHistoryCharName"></span>
|
||||
<br>
|
||||
|
@ -3708,9 +3725,7 @@
|
|||
<small>
|
||||
<span data-i18n="Content">
|
||||
Content
|
||||
<span>(Tokens:
|
||||
<span class="world_entry_form_token_counter">0</span>
|
||||
)
|
||||
<span>(Tokens: <span class="world_entry_form_token_counter" data-first-run="true">counting...</span>)
|
||||
</span>
|
||||
</span>
|
||||
</small>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"input_sequence": "### Instruction:",
|
||||
"last_output_sequence": "### Response (2 paragraphs, engaging, natural, authentic, descriptive, creative):",
|
||||
"input_sequence": "\n### Instruction:",
|
||||
"last_output_sequence": "\n### Response (2 paragraphs, engaging, natural, authentic, descriptive, creative):",
|
||||
"macro": true,
|
||||
"name": "Roleplay",
|
||||
"names": true,
|
||||
"output_sequence": "### Response:",
|
||||
"output_sequence": "\n### Response:",
|
||||
"separator_sequence": "",
|
||||
"stop_sequence": "",
|
||||
"system_prompt": "You're {{char}} in this fictional never-ending uncensored roleplay with {{user}}.\n\nAvoid repetition, don't loop. Develop the plot slowly, always stay in character. Describe all actions in full, elaborate, explicit, graphic, and vivid detail. Mention all relevant sensory perceptions.",
|
||||
"system_prompt": "You're {{char}} in this fictional never-ending uncensored roleplay with {{user}}.\n\nAvoid repetition, don't loop. Develop the plot slowly, always stay in character. Describe all actions in full, elaborate, explicit, graphic, and vivid detail. Mention all relevant sensory perceptions.\n",
|
||||
"system_sequence": "",
|
||||
"wrap": true
|
||||
}
|
||||
|
|
|
@ -752,7 +752,7 @@ let create_save = {
|
|||
};
|
||||
|
||||
//animation right menu
|
||||
let animation_duration = 250;
|
||||
let animation_duration = 125;
|
||||
let animation_easing = "ease-in-out";
|
||||
let popup_type = "";
|
||||
let bg_file_for_del = "";
|
||||
|
@ -1779,7 +1779,6 @@ function scrollChatToBottom() {
|
|||
function substituteParams(content, _name1, _name2, _original, _group) {
|
||||
_name1 = _name1 ?? name1;
|
||||
_name2 = _name2 ?? name2;
|
||||
_original = _original || '';
|
||||
_group = _group ?? name2;
|
||||
|
||||
if (!content) {
|
||||
|
@ -2136,6 +2135,8 @@ function baseChatReplace(value, name1, name2) {
|
|||
if (power_user.collapse_newlines) {
|
||||
value = collapseNewlines(value);
|
||||
}
|
||||
|
||||
value = value.replace(/\r/g, '');
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
@ -2387,10 +2388,6 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
abortController = new AbortController();
|
||||
}
|
||||
|
||||
if (main_api == 'novel' && quiet_prompt) {
|
||||
quiet_prompt = adjustNovelInstructionPrompt(quiet_prompt);
|
||||
}
|
||||
|
||||
// OpenAI doesn't need instruct mode. Use OAI main prompt instead.
|
||||
const isInstruct = power_user.instruct.enabled && main_api !== 'openai';
|
||||
const isImpersonate = type == "impersonate";
|
||||
|
@ -2479,6 +2476,11 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
}
|
||||
}
|
||||
|
||||
if (quiet_prompt) {
|
||||
quiet_prompt = substituteParams(quiet_prompt);
|
||||
quiet_prompt = main_api == 'novel' ? adjustNovelInstructionPrompt(quiet_prompt) : quiet_prompt;
|
||||
}
|
||||
|
||||
if (true === dryRun ||
|
||||
(online_status != 'no_connection' && this_chid != undefined && this_chid !== 'invalid-safety-id')) {
|
||||
let textareaText;
|
||||
|
@ -2538,8 +2540,8 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
let charPersonality = baseChatReplace(characters[this_chid].personality.trim(), name1, name2);
|
||||
let Scenario = baseChatReplace(scenarioText.trim(), name1, name2);
|
||||
let mesExamples = baseChatReplace(characters[this_chid].mes_example.trim(), name1, name2);
|
||||
let systemPrompt = baseChatReplace(characters[this_chid].data?.system_prompt?.trim(), name1, name2);
|
||||
let jailbreakPrompt = baseChatReplace(characters[this_chid].data?.post_history_instructions?.trim(), name1, name2);
|
||||
let systemPrompt = power_user.prefer_character_prompt ? baseChatReplace(characters[this_chid].data?.system_prompt?.trim(), name1, name2) : '';
|
||||
let jailbreakPrompt = power_user.prefer_character_jailbreak ? baseChatReplace(characters[this_chid].data?.post_history_instructions?.trim(), name1, name2) : '';
|
||||
|
||||
// Parse example messages
|
||||
if (!mesExamples.startsWith('<START>')) {
|
||||
|
@ -2995,8 +2997,9 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
bias: promptBias,
|
||||
type: type,
|
||||
quietPrompt: quiet_prompt,
|
||||
jailbreakPrompt: jailbreakPrompt,
|
||||
cyclePrompt: cyclePrompt,
|
||||
systemPromptOverride: systemPrompt,
|
||||
jailbreakPromptOverride: jailbreakPrompt,
|
||||
}, dryRun);
|
||||
generate_data = { prompt: prompt };
|
||||
|
||||
|
@ -5413,9 +5416,8 @@ async function getSettings(type) {
|
|||
setWorldInfoSettings(settings.world_info_settings ?? settings, data);
|
||||
|
||||
api_server_textgenerationwebui = settings.api_server_textgenerationwebui;
|
||||
$("#textgenerationwebui_api_url_text").val(
|
||||
api_server_textgenerationwebui
|
||||
);
|
||||
$("#textgenerationwebui_api_url_text").val(api_server_textgenerationwebui);
|
||||
$("#mancer_api_url_text").val(api_server_textgenerationwebui);
|
||||
api_use_mancer_webui = settings.api_use_mancer_webui
|
||||
$('#use-mancer-api-checkbox').prop("checked", api_use_mancer_webui);
|
||||
$('#use-mancer-api-checkbox').trigger("change");
|
||||
|
@ -5779,7 +5781,6 @@ export async function displayPastChats() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
displayChats(''); // Display all by default
|
||||
|
||||
|
@ -7529,7 +7530,7 @@ $(document).ready(function () {
|
|||
$("#character_search_bar").val("").trigger("input");
|
||||
});
|
||||
|
||||
$(document).on("click", ".character_select", function() {
|
||||
$(document).on("click", ".character_select", function () {
|
||||
const id = $(this).attr("chid");
|
||||
selectCharacterById(id);
|
||||
});
|
||||
|
@ -8013,7 +8014,9 @@ $(document).ready(function () {
|
|||
|
||||
$("#use-mancer-api-checkbox").on("change", function (e) {
|
||||
const enabled = $("#use-mancer-api-checkbox").prop("checked");
|
||||
$("#mancer-api-ui").toggle(enabled);
|
||||
$("#mancer_api_subpanel").toggle(enabled);
|
||||
$("#tgwebui_api_subpanel").toggle(!enabled);
|
||||
|
||||
api_use_mancer_webui = enabled;
|
||||
saveSettingsDebounced();
|
||||
getStatus();
|
||||
|
@ -8021,8 +8024,9 @@ $(document).ready(function () {
|
|||
|
||||
$("#api_button_textgenerationwebui").click(async function (e) {
|
||||
e.stopPropagation();
|
||||
if ($("#textgenerationwebui_api_url_text").val() != "") {
|
||||
let value = formatTextGenURL($("#textgenerationwebui_api_url_text").val().trim(), api_use_mancer_webui);
|
||||
const url_source = api_use_mancer_webui ? "#mancer_api_url_text" : "#textgenerationwebui_api_url_text";
|
||||
if ($(url_source).val() != "") {
|
||||
let value = formatTextGenURL($(url_source).val().trim(), api_use_mancer_webui);
|
||||
if (!value) {
|
||||
callPopup("Please enter a valid URL.<br/>WebUI URLs should end with <tt>/api</tt><br/>Enable 'Relaxed API URLs' to allow other paths.", 'text');
|
||||
return;
|
||||
|
@ -8033,9 +8037,13 @@ $(document).ready(function () {
|
|||
await writeSecret(SECRET_KEYS.MANCER, mancer_key);
|
||||
}
|
||||
|
||||
$("#textgenerationwebui_api_url_text").val(value);
|
||||
$(url_source).val(value);
|
||||
$("#api_loading_textgenerationwebui").css("display", "inline-block");
|
||||
$("#api_button_textgenerationwebui").css("display", "none");
|
||||
|
||||
if (api_use_mancer_webui) {
|
||||
textgenerationwebui_settings.streaming_url = value.replace("http", "ws") + "/v1/stream";
|
||||
}
|
||||
api_server_textgenerationwebui = value;
|
||||
main_api = "textgenerationwebui";
|
||||
saveSettingsDebounced();
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import {callPopup, event_types, eventSource, is_send_press, main_api, substituteParams} from "../script.js";
|
||||
"use strict";
|
||||
|
||||
import { callPopup, event_types, eventSource, is_send_press, main_api, substituteParams } from "../script.js";
|
||||
import { is_group_generating } from "./group-chats.js";
|
||||
import {TokenHandler} from "./openai.js";
|
||||
import {power_user} from "./power-user.js";
|
||||
import { TokenHandler } from "./openai.js";
|
||||
import { power_user } from "./power-user.js";
|
||||
import { debounce, waitUntilCondition } from "./utils.js";
|
||||
|
||||
function debouncePromise(func, delay) {
|
||||
|
@ -70,7 +72,7 @@ class Prompt {
|
|||
* @param {string} param0.name - The name of the prompt.
|
||||
* @param {boolean} param0.system_prompt - Indicates if the prompt is a system prompt.
|
||||
*/
|
||||
constructor({identifier, role, content, name, system_prompt} = {}) {
|
||||
constructor({ identifier, role, content, name, system_prompt } = {}) {
|
||||
this.identifier = identifier;
|
||||
this.role = role;
|
||||
this.content = content;
|
||||
|
@ -101,8 +103,8 @@ class PromptCollection {
|
|||
* @throws Will throw an error if one or more instances are not of the Prompt class.
|
||||
*/
|
||||
checkPromptInstance(...prompts) {
|
||||
for(let prompt of prompts) {
|
||||
if(!(prompt instanceof Prompt)) {
|
||||
for (let prompt of prompts) {
|
||||
if (!(prompt instanceof Prompt)) {
|
||||
throw new Error('Only Prompt instances can be added to PromptCollection');
|
||||
}
|
||||
}
|
||||
|
@ -250,7 +252,7 @@ function PromptManagerModule() {
|
|||
this.handleCharacterExport = () => { };
|
||||
|
||||
/** Character reset button click*/
|
||||
this.handleCharacterReset = () => {};
|
||||
this.handleCharacterReset = () => { };
|
||||
|
||||
/** Debounced version of render */
|
||||
this.renderDebounced = debounce(this.render.bind(this), 1000);
|
||||
|
@ -271,6 +273,8 @@ PromptManagerModule.prototype.init = function (moduleConfiguration, serviceSetti
|
|||
this.serviceSettings = serviceSettings;
|
||||
this.containerElement = document.getElementById(this.configuration.containerIdentifier);
|
||||
|
||||
if ('global' === this.configuration.promptOrder.strategy) this.activeCharacter = {id: this.configuration.promptOrder.dummyId};
|
||||
|
||||
this.sanitizeServiceSettings();
|
||||
|
||||
// Enable and disable prompts
|
||||
|
@ -382,7 +386,7 @@ PromptManagerModule.prototype.init = function (moduleConfiguration, serviceSetti
|
|||
const promptID = document.getElementById(this.configuration.prefix + 'prompt_manager_footer_append_prompt').value;
|
||||
const prompt = this.getPromptById(promptID);
|
||||
|
||||
if (prompt){
|
||||
if (prompt) {
|
||||
this.appendPrompt(prompt, this.activeCharacter);
|
||||
this.saveServiceSettings().then(() => this.render());
|
||||
}
|
||||
|
@ -390,7 +394,7 @@ PromptManagerModule.prototype.init = function (moduleConfiguration, serviceSetti
|
|||
|
||||
// Delete selected prompt from list form and close edit form
|
||||
this.handleDeletePrompt = (event) => {
|
||||
const promptID = document.getElementById(this.configuration.prefix + 'prompt_manager_footer_append_prompt').value;
|
||||
const promptID = document.getElementById(this.configuration.prefix + 'prompt_manager_footer_append_prompt').value;
|
||||
const prompt = this.getPromptById(promptID);
|
||||
|
||||
if (prompt && true === this.isPromptDeletionAllowed(prompt)) {
|
||||
|
@ -427,7 +431,7 @@ PromptManagerModule.prototype.init = function (moduleConfiguration, serviceSetti
|
|||
|
||||
let promptOrder = [];
|
||||
if ('global' === this.configuration.promptOrder.strategy) {
|
||||
promptOrder = this.getPromptOrderForCharacter({id: this.configuration.promptOrder.dummyId});
|
||||
promptOrder = this.getPromptOrderForCharacter({ id: this.configuration.promptOrder.dummyId });
|
||||
} else if ('character' === this.configuration.promptOrder.strategy) {
|
||||
promptOrder = [];
|
||||
} else {
|
||||
|
@ -490,10 +494,10 @@ PromptManagerModule.prototype.init = function (moduleConfiguration, serviceSetti
|
|||
};
|
||||
|
||||
reader.readAsText(file);
|
||||
});
|
||||
});
|
||||
|
||||
fileOpener.click();
|
||||
});
|
||||
fileOpener.click();
|
||||
});
|
||||
}
|
||||
|
||||
// Restore default state of a characters prompt order
|
||||
|
@ -556,7 +560,7 @@ PromptManagerModule.prototype.init = function (moduleConfiguration, serviceSetti
|
|||
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_save').addEventListener('click', this.handleSavePrompt);
|
||||
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_reset').addEventListener('click', this.handleResetPrompt);
|
||||
|
||||
const closeAndClearPopup = () => {
|
||||
const closeAndClearPopup = () => {
|
||||
this.hidePopup();
|
||||
this.clearEditForm();
|
||||
this.clearInspectForm();
|
||||
|
@ -590,7 +594,7 @@ PromptManagerModule.prototype.init = function (moduleConfiguration, serviceSetti
|
|||
PromptManagerModule.prototype.render = function (afterTryGenerate = true) {
|
||||
if (main_api !== 'openai') return;
|
||||
|
||||
if (null === this.activeCharacter) return;
|
||||
if ('character' === this.configuration.promptOrder.strategy && null === this.activeCharacter) return;
|
||||
this.error = null;
|
||||
|
||||
waitUntilCondition(() => !is_send_press && !is_group_generating, 1024 * 1024, 100).then(() => {
|
||||
|
@ -604,6 +608,11 @@ PromptManagerModule.prototype.render = function (afterTryGenerate = true) {
|
|||
this.renderPromptManagerListItems()
|
||||
this.makeDraggable();
|
||||
this.profileEnd('render');
|
||||
}).catch(error => {
|
||||
this.log('Error caught during render: ' + error);
|
||||
this.renderPromptManager();
|
||||
this.renderPromptManagerListItems()
|
||||
this.makeDraggable();
|
||||
});
|
||||
} else {
|
||||
// Executed during live communication
|
||||
|
@ -652,7 +661,7 @@ PromptManagerModule.prototype.updatePrompts = function (prompts) {
|
|||
})
|
||||
}
|
||||
|
||||
PromptManagerModule.prototype.getTokenHandler = function() {
|
||||
PromptManagerModule.prototype.getTokenHandler = function () {
|
||||
return this.tokenHandler;
|
||||
}
|
||||
|
||||
|
@ -666,7 +675,7 @@ PromptManagerModule.prototype.appendPrompt = function (prompt, character) {
|
|||
const promptOrder = this.getPromptOrderForCharacter(character);
|
||||
const index = promptOrder.findIndex(entry => entry.identifier === prompt.identifier);
|
||||
|
||||
if (-1 === index) promptOrder.push({identifier: prompt.identifier, enabled: false});
|
||||
if (-1 === index) promptOrder.push({ identifier: prompt.identifier, enabled: false });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -713,7 +722,7 @@ PromptManagerModule.prototype.sanitizeServiceSettings = function () {
|
|||
this.serviceSettings.prompt_order = this.serviceSettings.prompt_order ?? [];
|
||||
|
||||
if ('global' === this.configuration.promptOrder.strategy) {
|
||||
const dummyCharacter = {id: this.configuration.promptOrder.dummyId};
|
||||
const dummyCharacter = { id: this.configuration.promptOrder.dummyId };
|
||||
const promptOrder = this.getPromptOrderForCharacter(dummyCharacter);
|
||||
|
||||
if (0 === promptOrder.length) this.addPromptOrderForCharacter(dummyCharacter, promptManagerDefaultPromptOrder);
|
||||
|
@ -729,11 +738,11 @@ PromptManagerModule.prototype.sanitizeServiceSettings = function () {
|
|||
|
||||
if (this.activeCharacter) {
|
||||
const promptReferences = this.getPromptOrderForCharacter(this.activeCharacter);
|
||||
for(let i = promptReferences.length - 1; i >= 0; i--) {
|
||||
const reference = promptReferences[i];
|
||||
if(-1 === this.serviceSettings.prompts.findIndex(prompt => prompt.identifier === reference.identifier)) {
|
||||
for (let i = promptReferences.length - 1; i >= 0; i--) {
|
||||
const reference = promptReferences[i];
|
||||
if (-1 === this.serviceSettings.prompts.findIndex(prompt => prompt.identifier === reference.identifier)) {
|
||||
promptReferences.splice(i, 1);
|
||||
this.log('Removed unused reference: ' + reference.identifier);
|
||||
this.log('Removed unused reference: ' + reference.identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -745,11 +754,11 @@ PromptManagerModule.prototype.sanitizeServiceSettings = function () {
|
|||
*
|
||||
* @param prompts
|
||||
*/
|
||||
PromptManagerModule.prototype.checkForMissingPrompts = function(prompts) {
|
||||
const defaultPromptIdentifiers = chatCompletionDefaultPrompts.prompts.reduce((list, prompt) => { list.push(prompt.identifier); return list;}, []);
|
||||
PromptManagerModule.prototype.checkForMissingPrompts = function (prompts) {
|
||||
const defaultPromptIdentifiers = chatCompletionDefaultPrompts.prompts.reduce((list, prompt) => { list.push(prompt.identifier); return list; }, []);
|
||||
|
||||
const missingIdentifiers = defaultPromptIdentifiers.filter(identifier =>
|
||||
!prompts.some(prompt =>prompt.identifier === identifier)
|
||||
!prompts.some(prompt => prompt.identifier === identifier)
|
||||
);
|
||||
|
||||
missingIdentifiers.forEach(identifier => {
|
||||
|
@ -815,10 +824,10 @@ PromptManagerModule.prototype.handleCharacterDeleted = function (event) {
|
|||
*/
|
||||
PromptManagerModule.prototype.handleCharacterSelected = function (event) {
|
||||
if ('global' === this.configuration.promptOrder.strategy) {
|
||||
this.activeCharacter = {id: this.configuration.promptOrder.dummyId};
|
||||
} else if ('character' === this.configuration.promptOrder.strategy) {
|
||||
this.activeCharacter = { id: this.configuration.promptOrder.dummyId };
|
||||
} else if ('character' === this.configuration.promptOrder.strategy) {
|
||||
console.log('FOO')
|
||||
this.activeCharacter = {id: event.detail.id, ...event.detail.character};
|
||||
this.activeCharacter = { id: event.detail.id, ...event.detail.character };
|
||||
const promptOrder = this.getPromptOrderForCharacter(this.activeCharacter);
|
||||
|
||||
// ToDo: These should be passed as parameter or attached to the manager as a set of default options.
|
||||
|
@ -836,11 +845,11 @@ PromptManagerModule.prototype.handleCharacterSelected = function (event) {
|
|||
*/
|
||||
PromptManagerModule.prototype.handleCharacterUpdated = function (event) {
|
||||
if ('global' === this.configuration.promptOrder.strategy) {
|
||||
this.activeCharacter = {id: this.configuration.promptOrder.dummyId};
|
||||
this.activeCharacter = { id: this.configuration.promptOrder.dummyId };
|
||||
} else if ('character' === this.configuration.promptOrder.strategy) {
|
||||
this.activeCharacter = {id: event.detail.id, ...event.detail.character};
|
||||
this.activeCharacter = { id: event.detail.id, ...event.detail.character };
|
||||
} else {
|
||||
throw new Error ('Prompt order strategy not supported.')
|
||||
throw new Error('Prompt order strategy not supported.')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -851,15 +860,15 @@ PromptManagerModule.prototype.handleCharacterUpdated = function (event) {
|
|||
*/
|
||||
PromptManagerModule.prototype.handleGroupSelected = function (event) {
|
||||
if ('global' === this.configuration.promptOrder.strategy) {
|
||||
this.activeCharacter = {id: this.configuration.promptOrder.dummyId};
|
||||
this.activeCharacter = { id: this.configuration.promptOrder.dummyId };
|
||||
} else if ('character' === this.configuration.promptOrder.strategy) {
|
||||
const characterDummy = {id: event.detail.id, group: event.detail.group};
|
||||
const characterDummy = { id: event.detail.id, group: event.detail.group };
|
||||
this.activeCharacter = characterDummy;
|
||||
const promptOrder = this.getPromptOrderForCharacter(characterDummy);
|
||||
|
||||
if (0 === promptOrder.length) this.addPromptOrderForCharacter(characterDummy, promptManagerDefaultPromptOrder)
|
||||
} else {
|
||||
throw new Error ('Prompt order strategy not supported.')
|
||||
throw new Error('Prompt order strategy not supported.')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -868,7 +877,7 @@ PromptManagerModule.prototype.handleGroupSelected = function (event) {
|
|||
*
|
||||
* @returns {string[]}
|
||||
*/
|
||||
PromptManagerModule.prototype.getActiveGroupCharacters = function() {
|
||||
PromptManagerModule.prototype.getActiveGroupCharacters = function () {
|
||||
// ToDo: Ideally, this should return the actual characters.
|
||||
return (this.activeCharacter?.group?.members || []).map(member => member && member.substring(0, member.lastIndexOf('.')));
|
||||
}
|
||||
|
@ -982,7 +991,7 @@ PromptManagerModule.prototype.preparePrompt = function (prompt, original = null)
|
|||
* and handle input events to update the prompt content.
|
||||
*
|
||||
*/
|
||||
PromptManagerModule.prototype.createQuickEdit = function(identifier, title) {
|
||||
PromptManagerModule.prototype.createQuickEdit = function (identifier, title) {
|
||||
const prompt = this.getPromptById(identifier);
|
||||
const textareaIdentifier = `${identifier}_prompt_quick_edit_textarea`;
|
||||
const html = `<div class="range-block m-t-1">
|
||||
|
@ -1006,7 +1015,7 @@ PromptManagerModule.prototype.createQuickEdit = function(identifier, title) {
|
|||
|
||||
}
|
||||
|
||||
PromptManagerModule.prototype.updateQuickEdit = function(identifier, prompt) {
|
||||
PromptManagerModule.prototype.updateQuickEdit = function (identifier, prompt) {
|
||||
const textarea = document.getElementById(`${identifier}_prompt_quick_edit_textarea`);
|
||||
textarea.value = prompt.content;
|
||||
}
|
||||
|
@ -1018,13 +1027,13 @@ PromptManagerModule.prototype.updateQuickEdit = function(identifier, prompt) {
|
|||
* @param name
|
||||
* @returns {boolean}
|
||||
*/
|
||||
PromptManagerModule.prototype.isValidName = function(name) {
|
||||
PromptManagerModule.prototype.isValidName = function (name) {
|
||||
const regex = /^[a-zA-Z0-9_]{1,64}$/;
|
||||
|
||||
return regex.test(name);
|
||||
}
|
||||
|
||||
PromptManagerModule.prototype.sanitizeName = function(name) {
|
||||
PromptManagerModule.prototype.sanitizeName = function (name) {
|
||||
return name.replace(/[^a-zA-Z0-9_]/g, '_').substring(0, 64);
|
||||
}
|
||||
|
||||
|
@ -1111,7 +1120,7 @@ PromptManagerModule.prototype.clearEditForm = function () {
|
|||
roleField.disabled = false;
|
||||
}
|
||||
|
||||
PromptManagerModule.prototype.clearInspectForm = function() {
|
||||
PromptManagerModule.prototype.clearInspectForm = function () {
|
||||
const inspectArea = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_inspect');
|
||||
inspectArea.style.display = 'none';
|
||||
const messageList = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_inspect_list');
|
||||
|
@ -1150,7 +1159,7 @@ PromptManagerModule.prototype.setMessages = function (messages) {
|
|||
*
|
||||
* @param {ChatCompletion} chatCompletion
|
||||
*/
|
||||
PromptManagerModule.prototype.setChatCompletion = function(chatCompletion) {
|
||||
PromptManagerModule.prototype.setChatCompletion = function (chatCompletion) {
|
||||
const messages = chatCompletion.getMessages();
|
||||
|
||||
this.setMessages(messages);
|
||||
|
@ -1163,7 +1172,7 @@ PromptManagerModule.prototype.setChatCompletion = function(chatCompletion) {
|
|||
*
|
||||
* @param {MessageCollection} messages
|
||||
*/
|
||||
PromptManagerModule.prototype.populateTokenCounts = function(messages) {
|
||||
PromptManagerModule.prototype.populateTokenCounts = function (messages) {
|
||||
this.tokenHandler.resetCounts();
|
||||
const counts = this.tokenHandler.getCounts();
|
||||
messages.getCollection().forEach(message => {
|
||||
|
@ -1182,7 +1191,7 @@ PromptManagerModule.prototype.populateTokenCounts = function(messages) {
|
|||
*
|
||||
* @param {MessageCollection} messages
|
||||
*/
|
||||
PromptManagerModule.prototype.populateLegacyTokenCounts = function(messages) {
|
||||
PromptManagerModule.prototype.populateLegacyTokenCounts = function (messages) {
|
||||
// Update general token counts
|
||||
const chatHistory = messages.getItemByIdentifier('chatHistory');
|
||||
const startChat = chatHistory?.getCollection()[0].getTokens() || 0;
|
||||
|
@ -1246,8 +1255,8 @@ PromptManagerModule.prototype.renderPromptManager = function () {
|
|||
</select>
|
||||
<a class="menu_button fa-chain fa-solid" title="Insert prompt" data-i18n="Insert"></a>
|
||||
<a class="caution menu_button fa-x fa-solid" title="Delete prompt" data-i18n="Delete"></a>
|
||||
<a class="menu_button fa-file-arrow-down fa-solid" id="prompt-manager-export" title="Export this prompt list" data-i18n="Export"></a>
|
||||
<a class="menu_button fa-file-arrow-up fa-solid" id="prompt-manager-import" title="Import a prompt list" data-i18n="Import"></a>
|
||||
<a class="menu_button fa-file-import fa-solid" id="prompt-manager-import" title="Import a prompt list" data-i18n="Import"></a>
|
||||
<a class="menu_button fa-file-export fa-solid" id="prompt-manager-export" title="Export this prompt list" data-i18n="Export"></a>
|
||||
<a class="menu_button fa-undo fa-solid" id="prompt-manager-reset-character" title="Reset current character" data-i18n="Reset current character"></a>
|
||||
<a class="menu_button fa-plus-square fa-solid" title="New prompt" data-i18n="New"></a>
|
||||
</div>
|
||||
|
@ -1270,9 +1279,9 @@ PromptManagerModule.prototype.renderPromptManager = function () {
|
|||
<a class="export-promptmanager-prompts-full list-group-item" data-i18n="Export all">Export all</a>
|
||||
<span class="tooltip fa-solid fa-info-circle" title="Export all your prompts to a file"></span>
|
||||
</div>
|
||||
${ 'global' === this.configuration.promptOrder.strategy
|
||||
? ''
|
||||
: `<div class="row">
|
||||
${'global' === this.configuration.promptOrder.strategy
|
||||
? ''
|
||||
: `<div class="row">
|
||||
<a class="export-promptmanager-prompts-character list-group-item" data-i18n="Export for character">Export
|
||||
for character</a>
|
||||
<span class="tooltip fa-solid fa-info-circle"
|
||||
|
@ -1287,7 +1296,7 @@ PromptManagerModule.prototype.renderPromptManager = function () {
|
|||
let exportPopper = Popper.createPopper(
|
||||
document.getElementById('prompt-manager-export'),
|
||||
document.getElementById('prompt-manager-export-format-popup'),
|
||||
{placement: 'bottom'}
|
||||
{ placement: 'bottom' }
|
||||
);
|
||||
|
||||
const showExportSelection = () => {
|
||||
|
@ -1306,14 +1315,46 @@ PromptManagerModule.prototype.renderPromptManager = function () {
|
|||
rangeBlockDiv.querySelector('.export-promptmanager-prompts-character')?.addEventListener('click', this.handleCharacterExport);
|
||||
|
||||
const quickEditContainer = document.getElementById('quick-edit-container');
|
||||
const heights = this.saveTextAreaHeights(quickEditContainer);
|
||||
quickEditContainer.innerHTML = '';
|
||||
|
||||
this.createQuickEdit('jailbreak', 'Jailbreak');
|
||||
this.createQuickEdit('nsfw', 'NSFW');
|
||||
this.createQuickEdit('main', 'Main');
|
||||
|
||||
this.restoreTextAreaHeights(quickEditContainer, heights);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Restores the height of each textarea in the container
|
||||
* @param container The container to search for textareas
|
||||
* @param heights An object with textarea ids as keys and heights as values
|
||||
*/
|
||||
PromptManagerModule.prototype.restoreTextAreaHeights = function(container, heights) {
|
||||
if (Object.keys(heights).length === 0) return;
|
||||
|
||||
$(container).find('textarea').each(function () {
|
||||
const height = heights[this.id];
|
||||
if (height > 0) $(this).height(height);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the current height of each textarea in the container
|
||||
* @param container The container to search for textareas
|
||||
* @returns {{}} An object with textarea ids as keys and heights as values
|
||||
*/
|
||||
PromptManagerModule.prototype.saveTextAreaHeights = function(container) {
|
||||
const heights = {};
|
||||
|
||||
$(container).find('textarea').each(function () {
|
||||
heights[this.id] = $(this).height();
|
||||
});
|
||||
|
||||
return heights;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties, then re-assembles the prompt list
|
||||
*/
|
||||
|
@ -1323,7 +1364,7 @@ PromptManagerModule.prototype.renderPromptManagerListItems = function () {
|
|||
const promptManagerList = this.listElement;
|
||||
promptManagerList.innerHTML = '';
|
||||
|
||||
const {prefix} = this.configuration;
|
||||
const { prefix } = this.configuration;
|
||||
|
||||
let listItemHtml = `
|
||||
<li class="${prefix}prompt_manager_list_head">
|
||||
|
@ -1350,7 +1391,7 @@ PromptManagerModule.prototype.renderPromptManagerListItems = function () {
|
|||
let warningTitle = '';
|
||||
|
||||
const tokenBudget = this.serviceSettings.openai_max_context - this.serviceSettings.openai_max_tokens;
|
||||
if ( this.tokenUsage > tokenBudget * 0.8 &&
|
||||
if (this.tokenUsage > tokenBudget * 0.8 &&
|
||||
'chatHistory' === prompt.identifier) {
|
||||
const warningThreshold = this.configuration.warningTokenThreshold;
|
||||
const dangerThreshold = this.configuration.dangerTokenThreshold;
|
||||
|
@ -1399,7 +1440,7 @@ PromptManagerModule.prototype.renderPromptManagerListItems = function () {
|
|||
${prompt.marker ? '<span class="fa-solid fa-thumb-tack" title="Marker"></span>' : ''}
|
||||
${!prompt.marker && prompt.system_prompt ? '<span class="fa-solid fa-square-poll-horizontal" title="Global Prompt"></span>' : ''}
|
||||
${!prompt.marker && !prompt.system_prompt ? '<span class="fa-solid fa-user" title="User Prompt"></span>' : ''}
|
||||
${this.isPromptInspectionAllowed(prompt) ? `<a class="prompt-manager-inspect-action">${prompt.name}</a>` : prompt.name }
|
||||
${this.isPromptInspectionAllowed(prompt) ? `<a class="prompt-manager-inspect-action">${prompt.name}</a>` : prompt.name}
|
||||
</span>
|
||||
<span>
|
||||
<span class="prompt_manager_prompt_controls">
|
||||
|
@ -1449,7 +1490,7 @@ PromptManagerModule.prototype.export = function (data, type, name = 'export') {
|
|||
};
|
||||
|
||||
const serializedObject = JSON.stringify(promptExport);
|
||||
const blob = new Blob([serializedObject], {type: "application/json"});
|
||||
const blob = new Blob([serializedObject], { type: "application/json" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const downloadLink = document.createElement('a');
|
||||
downloadLink.href = url;
|
||||
|
@ -1502,7 +1543,7 @@ PromptManagerModule.prototype.import = function (importData) {
|
|||
|
||||
let promptOrder = [];
|
||||
if ('global' === this.configuration.promptOrder.strategy) {
|
||||
const promptOrder = this.getPromptOrderForCharacter({id: this.configuration.promptOrder.dummyId});
|
||||
const promptOrder = this.getPromptOrderForCharacter({ id: this.configuration.promptOrder.dummyId });
|
||||
Object.assign(promptOrder, importData.data.prompt_order);
|
||||
this.log(`Prompt order import succeeded`);
|
||||
} else if ('character' === this.configuration.promptOrder.strategy) {
|
||||
|
@ -1526,7 +1567,7 @@ PromptManagerModule.prototype.import = function (importData) {
|
|||
* @param object
|
||||
* @returns {boolean}
|
||||
*/
|
||||
PromptManagerModule.prototype.validateObject = function(controlObj, object) {
|
||||
PromptManagerModule.prototype.validateObject = function (controlObj, object) {
|
||||
for (let key in controlObj) {
|
||||
if (!object.hasOwnProperty(key)) {
|
||||
if (controlObj[key] === null) continue;
|
||||
|
@ -1549,7 +1590,7 @@ PromptManagerModule.prototype.validateObject = function(controlObj, object) {
|
|||
*
|
||||
* @returns {`${string}_${string}_${string}`}
|
||||
*/
|
||||
PromptManagerModule.prototype.getFormattedDate = function() {
|
||||
PromptManagerModule.prototype.getFormattedDate = function () {
|
||||
const date = new Date();
|
||||
let month = String(date.getMonth() + 1);
|
||||
let day = String(date.getDate());
|
||||
|
@ -1571,9 +1612,9 @@ PromptManagerModule.prototype.makeDraggable = function () {
|
|||
$(`#${this.configuration.prefix}prompt_manager_list`).sortable({
|
||||
delay: this.configuration.sortableDelay,
|
||||
items: `.${this.configuration.prefix}prompt_manager_prompt_draggable`,
|
||||
update: ( event, ui ) => {
|
||||
update: (event, ui) => {
|
||||
const promptOrder = this.getPromptOrderForCharacter(this.activeCharacter);
|
||||
const promptListElement = $(`#${this.configuration.prefix}prompt_manager_list`).sortable('toArray', {attribute: 'data-pm-identifier'});
|
||||
const promptListElement = $(`#${this.configuration.prefix}prompt_manager_list`).sortable('toArray', { attribute: 'data-pm-identifier' });
|
||||
const idToObjectMap = new Map(promptOrder.map(prompt => [prompt.identifier, prompt]));
|
||||
const updatedPromptOrder = promptListElement.map(identifier => idToObjectMap.get(identifier));
|
||||
|
||||
|
@ -1583,7 +1624,8 @@ PromptManagerModule.prototype.makeDraggable = function () {
|
|||
this.log(`Prompt order updated for ${this.activeCharacter.name}.`);
|
||||
|
||||
this.saveServiceSettings();
|
||||
}});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1594,7 +1636,7 @@ PromptManagerModule.prototype.showPopup = function (area = 'edit') {
|
|||
const areaElement = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_' + area);
|
||||
areaElement.style.display = 'block';
|
||||
|
||||
$('#'+this.configuration.prefix +'prompt_manager_popup').first()
|
||||
$('#' + this.configuration.prefix + 'prompt_manager_popup').first()
|
||||
.slideDown(200, "swing")
|
||||
.addClass('openDrawer');
|
||||
}
|
||||
|
@ -1604,7 +1646,7 @@ PromptManagerModule.prototype.showPopup = function (area = 'edit') {
|
|||
* @returns {void}
|
||||
*/
|
||||
PromptManagerModule.prototype.hidePopup = function () {
|
||||
$('#'+this.configuration.prefix +'prompt_manager_popup').first()
|
||||
$('#' + this.configuration.prefix + 'prompt_manager_popup').first()
|
||||
.slideUp(200, "swing")
|
||||
.removeClass('openDrawer');
|
||||
}
|
||||
|
|
|
@ -33,12 +33,12 @@ import {
|
|||
} from "./power-user.js";
|
||||
|
||||
import { LoadLocal, SaveLocal, CheckLocal, LoadLocalBool } from "./f-localStorage.js";
|
||||
import { selected_group, is_group_generating, getGroupAvatar, groups } from "./group-chats.js";
|
||||
import { selected_group, is_group_generating, getGroupAvatar, groups, openGroupById } from "./group-chats.js";
|
||||
import {
|
||||
SECRET_KEYS,
|
||||
secret_state,
|
||||
} from "./secrets.js";
|
||||
import { sortByCssOrder, debounce, delay } from "./utils.js";
|
||||
import { debounce, delay } from "./utils.js";
|
||||
import { chat_completion_sources, oai_settings } from "./openai.js";
|
||||
|
||||
var NavToggle = document.getElementById("nav-toggle");
|
||||
|
@ -354,10 +354,8 @@ async function RA_autoloadchat() {
|
|||
selectCharacterById(String(active_character_id));
|
||||
}
|
||||
|
||||
let groupToAutoLoad = document.querySelector(`.group_select[grid="${active_group}"]`);
|
||||
|
||||
if (groupToAutoLoad != null) {
|
||||
$(groupToAutoLoad).click();
|
||||
if (active_group != null) {
|
||||
openGroupById(String(active_group));
|
||||
}
|
||||
|
||||
// if the character list hadn't been loaded yet, try again.
|
||||
|
@ -395,17 +393,18 @@ export async function favsToHotswap() {
|
|||
slot.attr('grid', isGroup ? grid : '');
|
||||
slot.attr('chid', isCharacter ? chid : '');
|
||||
slot.data('id', isGroup ? grid : chid);
|
||||
slot.attr('title', '');
|
||||
|
||||
if (isGroup) {
|
||||
const group = groups.find(x => x.id === grid);
|
||||
const avatar = getGroupAvatar(group);
|
||||
$(slot).find('img').replaceWith(avatar);
|
||||
$(slot).attr('title', group.name);
|
||||
}
|
||||
|
||||
if (isCharacter) {
|
||||
const avatarUrl = getThumbnailUrl('avatar', entity.item.avatar);
|
||||
$(slot).find('img').attr('src', avatarUrl);
|
||||
$(slot).attr('title', entity.item.avatar);
|
||||
}
|
||||
|
||||
$(slot).css('cursor', 'pointer');
|
||||
|
@ -933,14 +932,16 @@ $("document").ready(function () {
|
|||
|
||||
// when a char is selected from the list, save their name as the auto-load character for next page load
|
||||
$(document).on("click", ".character_select", function () {
|
||||
setActiveCharacter($(this).find('.avatar').attr('title'));
|
||||
const characterId = $(this).find('.avatar').attr('title') || $(this).attr('title');
|
||||
setActiveCharacter(characterId);
|
||||
setActiveGroup(null);
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
$(document).on("click", ".group_select", function () {
|
||||
const groupId = $(this).data('id') || $(this).attr('grid');
|
||||
setActiveCharacter(null);
|
||||
setActiveGroup($(this).data('id'));
|
||||
setActiveGroup(groupId);
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import {
|
||||
characters,
|
||||
saveChat,
|
||||
sendSystemMessage,
|
||||
system_messages,
|
||||
system_message_types,
|
||||
this_chid,
|
||||
|
@ -19,6 +18,7 @@ import {
|
|||
getGroupPastChats,
|
||||
group_activation_strategy,
|
||||
groups,
|
||||
openGroupById,
|
||||
openGroupChat,
|
||||
saveGroupBookmarkChat,
|
||||
selected_group,
|
||||
|
@ -301,13 +301,12 @@ async function convertSoloToGroupChat() {
|
|||
}
|
||||
|
||||
// Click on the freshly selected group to open it
|
||||
$(`.group_select[grid="${group.id}"]`).click();
|
||||
await openGroupById(group.id);
|
||||
|
||||
await delay(1);
|
||||
toastr.success('The chat has been successfully converted!');
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
jQuery(function () {
|
||||
$('#option_new_bookmark').on('click', saveBookmarkMenu);
|
||||
$('#option_back_to_main').on('click', backToMainChat);
|
||||
$('#option_convert_to_group').on('click', convertSoloToGroupChat);
|
||||
|
|
|
@ -499,7 +499,7 @@ async function moduleWorker() {
|
|||
const context = getContext();
|
||||
|
||||
// non-characters not supported
|
||||
if (!context.groupId && context.characterId === undefined) {
|
||||
if (!context.groupId && (context.characterId === undefined || context.characterId === 'invalid-safety-id')) {
|
||||
removeExpression();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import {
|
||||
substituteParams,
|
||||
saveSettingsDebounced,
|
||||
systemUserName,
|
||||
hideSwipeButtons,
|
||||
|
@ -14,7 +13,8 @@ import {
|
|||
} from "../../../script.js";
|
||||
import { getApiUrl, getContext, extension_settings, doExtrasFetch, modules } from "../../extensions.js";
|
||||
import { selected_group } from "../../group-chats.js";
|
||||
import { stringFormat, initScrollHeight, resetScrollHeight, timestampToMoment, getCharaFilename } from "../../utils.js";
|
||||
import { stringFormat, initScrollHeight, resetScrollHeight, timestampToMoment, getCharaFilename, saveBase64AsFile } from "../../utils.js";
|
||||
import { humanizedDateTime } from "../../RossAscends-mods.js";
|
||||
export { MODULE_NAME };
|
||||
|
||||
// Wraps a string into monospace font-face span
|
||||
|
@ -512,7 +512,7 @@ function getQuietPrompt(mode, trigger) {
|
|||
return trigger;
|
||||
}
|
||||
|
||||
return substituteParams(stringFormat(extension_settings.sd.prompts[mode], trigger));
|
||||
return stringFormat(extension_settings.sd.prompts[mode], trigger);
|
||||
}
|
||||
|
||||
function processReply(str) {
|
||||
|
@ -537,6 +537,7 @@ function processReply(str) {
|
|||
return str;
|
||||
}
|
||||
|
||||
|
||||
function getRawLastMessage() {
|
||||
const context = getContext();
|
||||
const lastMessage = context.chat.slice(-1)[0].mes,
|
||||
|
@ -565,6 +566,10 @@ async function generatePicture(_, trigger, message, callback) {
|
|||
const quiet_prompt = getQuietPrompt(generationType, trigger);
|
||||
const context = getContext();
|
||||
|
||||
// if context.characterId is not null, then we get context.characters[context.characterId].avatar, else we get groupId and context.groups[groupId].id
|
||||
// sadly, groups is not an array, but is a dict with keys being index numbers, so we have to filter it
|
||||
const characterName = context.characterId ? context.characters[context.characterId].name : context.groups[Object.keys(context.groups).filter(x => context.groups[x].id === context.groupId)[0]].id.toString();
|
||||
|
||||
const prevSDHeight = extension_settings.sd.height;
|
||||
const prevSDWidth = extension_settings.sd.width;
|
||||
const aspectRatio = extension_settings.sd.width / extension_settings.sd.height;
|
||||
|
@ -580,8 +585,10 @@ async function generatePicture(_, trigger, message, callback) {
|
|||
// Round to nearest multiple of 64
|
||||
extension_settings.sd.width = Math.round(extension_settings.sd.height * 1.8 / 64) * 64;
|
||||
const callbackOriginal = callback;
|
||||
callback = function (prompt, base64Image) {
|
||||
const imgUrl = `url(${base64Image})`;
|
||||
callback = async function (prompt, base64Image) {
|
||||
const imagePath = base64Image;
|
||||
const imgUrl = `url('${encodeURIComponent(base64Image)}')`;
|
||||
|
||||
if ('forceSetBackground' in window) {
|
||||
forceSetBackground(imgUrl);
|
||||
} else {
|
||||
|
@ -590,9 +597,9 @@ async function generatePicture(_, trigger, message, callback) {
|
|||
}
|
||||
|
||||
if (typeof callbackOriginal === 'function') {
|
||||
callbackOriginal(prompt, base64Image);
|
||||
callbackOriginal(prompt, imagePath);
|
||||
} else {
|
||||
sendMessage(prompt, base64Image);
|
||||
sendMessage(prompt, imagePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -604,7 +611,7 @@ async function generatePicture(_, trigger, message, callback) {
|
|||
context.deactivateSendButtons();
|
||||
hideSwipeButtons();
|
||||
|
||||
await sendGenerationRequest(generationType, prompt, callback);
|
||||
await sendGenerationRequest(generationType, prompt, characterName, callback);
|
||||
} catch (err) {
|
||||
console.trace(err);
|
||||
throw new Error('SD prompt text generation failed.')
|
||||
|
@ -644,19 +651,31 @@ async function generatePrompt(quiet_prompt) {
|
|||
return processReply(reply);
|
||||
}
|
||||
|
||||
async function sendGenerationRequest(generationType, prompt, callback) {
|
||||
async function sendGenerationRequest(generationType, prompt, characterName = null, callback) {
|
||||
const prefix = generationType !== generationMode.BACKGROUND
|
||||
? combinePrefixes(extension_settings.sd.prompt_prefix, getCharacterPrefix())
|
||||
: extension_settings.sd.prompt_prefix;
|
||||
|
||||
if (extension_settings.sd.horde) {
|
||||
await generateHordeImage(prompt, prefix, callback);
|
||||
await generateHordeImage(prompt, prefix, characterName, callback);
|
||||
} else {
|
||||
await generateExtrasImage(prompt, prefix, callback);
|
||||
await generateExtrasImage(prompt, prefix, characterName, callback);
|
||||
}
|
||||
}
|
||||
|
||||
async function generateExtrasImage(prompt, prefix, callback) {
|
||||
/**
|
||||
* Generates an "extras" image using a provided prompt and other settings,
|
||||
* then saves the generated image and either invokes a callback or sends a message with the image.
|
||||
*
|
||||
* @param {string} prompt - The main instruction used to guide the image generation.
|
||||
* @param {string} prefix - Additional context or prefix to guide the image generation.
|
||||
* @param {string} characterName - The name used to determine the sub-directory for saving.
|
||||
* @param {function} [callback] - Optional callback function invoked with the prompt and saved image.
|
||||
* If not provided, `sendMessage` is called instead.
|
||||
*
|
||||
* @returns {Promise<void>} - A promise that resolves when the image generation and processing are complete.
|
||||
*/
|
||||
async function generateExtrasImage(prompt, prefix, characterName, callback) {
|
||||
console.debug(extension_settings.sd);
|
||||
const url = new URL(getApiUrl());
|
||||
url.pathname = '/api/image';
|
||||
|
@ -680,14 +699,28 @@ async function generateExtrasImage(prompt, prefix, callback) {
|
|||
|
||||
if (result.ok) {
|
||||
const data = await result.json();
|
||||
const base64Image = `data:image/jpeg;base64,${data.image}`;
|
||||
//filename should be character name + human readable timestamp + generation mode
|
||||
const filename = `${characterName}_${humanizedDateTime()}`;
|
||||
const base64Image = await saveBase64AsFile(data.image, characterName, filename, "jpg");
|
||||
callback ? callback(prompt, base64Image) : sendMessage(prompt, base64Image);
|
||||
} else {
|
||||
callPopup('Image generation has failed. Please try again.', 'text');
|
||||
}
|
||||
}
|
||||
|
||||
async function generateHordeImage(prompt, prefix, callback) {
|
||||
/**
|
||||
* Generates a "horde" image using the provided prompt and configuration settings,
|
||||
* then saves the generated image and either invokes a callback or sends a message with the image.
|
||||
*
|
||||
* @param {string} prompt - The main instruction used to guide the image generation.
|
||||
* @param {string} prefix - Additional context or prefix to guide the image generation.
|
||||
* @param {string} characterName - The name used to determine the sub-directory for saving.
|
||||
* @param {function} [callback] - Optional callback function invoked with the prompt and saved image.
|
||||
* If not provided, `sendMessage` is called instead.
|
||||
*
|
||||
* @returns {Promise<void>} - A promise that resolves when the image generation and processing are complete.
|
||||
*/
|
||||
async function generateHordeImage(prompt, prefix, characterName, callback) {
|
||||
const result = await fetch('/horde_generateimage', {
|
||||
method: 'POST',
|
||||
headers: getRequestHeaders(),
|
||||
|
@ -709,7 +742,8 @@ async function generateHordeImage(prompt, prefix, callback) {
|
|||
|
||||
if (result.ok) {
|
||||
const data = await result.text();
|
||||
const base64Image = `data:image/webp;base64,${data}`;
|
||||
const filename = `${characterName}_${humanizedDateTime()}`;
|
||||
const base64Image = await saveBase64AsFile(data, characterName, filename, "webp");
|
||||
callback ? callback(prompt, base64Image) : sendMessage(prompt, base64Image);
|
||||
} else {
|
||||
toastr.error('Image generation has failed. Please try again.');
|
||||
|
@ -827,7 +861,7 @@ async function sdMessageButton(e) {
|
|||
const message_id = $mes.attr('mesid');
|
||||
const message = context.chat[message_id];
|
||||
const characterName = message?.name || context.name2;
|
||||
const messageText = substituteParams(message?.mes);
|
||||
const messageText = message?.mes;
|
||||
const hasSavedImage = message?.extra?.image && message?.extra?.title;
|
||||
|
||||
if ($icon.hasClass(busyClass)) {
|
||||
|
@ -842,7 +876,7 @@ async function sdMessageButton(e) {
|
|||
message.extra.title = prompt;
|
||||
|
||||
console.log('Regenerating an image, using existing prompt:', prompt);
|
||||
await sendGenerationRequest(generationMode.FREE, prompt, saveGeneratedImage);
|
||||
await sendGenerationRequest(generationMode.FREE, prompt, characterName, saveGeneratedImage);
|
||||
}
|
||||
else {
|
||||
console.log("doing /sd raw last");
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
isDataURL,
|
||||
createThumbnail,
|
||||
extractAllWords,
|
||||
saveBase64AsFile
|
||||
} from './utils.js';
|
||||
import { RA_CountCharTokens, humanizedDateTime, dragElement, favsToHotswap } from "./RossAscends-mods.js";
|
||||
import { loadMovingUIState, sortEntitiesList } from './power-user.js';
|
||||
|
@ -63,8 +64,8 @@ import {
|
|||
getCropPopup,
|
||||
system_avatar,
|
||||
} from "../script.js";
|
||||
import { appendTagToList, createTagMapFromList, getTagsList, applyTagsOnCharacterSelect, tag_map } from './tags.js';
|
||||
import { FilterHelper } from './filters.js';
|
||||
import { appendTagToList, createTagMapFromList, getTagsList, applyTagsOnCharacterSelect, tag_map, printTagFilters } from './tags.js';
|
||||
import { FILTER_TYPES, FilterHelper } from './filters.js';
|
||||
|
||||
export {
|
||||
selected_group,
|
||||
|
@ -309,6 +310,9 @@ async function getGroups() {
|
|||
|
||||
// Convert groups to new format
|
||||
for (const group of groups) {
|
||||
if (typeof group.id === 'number') {
|
||||
group.id = String(group.id);
|
||||
}
|
||||
if (group.disabled_members == undefined) {
|
||||
group.disabled_members = [];
|
||||
}
|
||||
|
@ -334,25 +338,25 @@ async function getGroups() {
|
|||
}
|
||||
|
||||
export function getGroupBlock(group) {
|
||||
const template = $("#group_list_template .group_select").clone();
|
||||
template.data("id", group.id);
|
||||
template.attr("grid", group.id);
|
||||
template.find(".ch_name").html(group.name).css('color', group.fav ? 'gold' : 'white');
|
||||
template.find('.group_fav_icon').css("display", 'none');
|
||||
template.addClass(group.fav ? 'is_fav' : '');
|
||||
template.find(".ch_fav").val(group.fav);
|
||||
const template = $("#group_list_template .group_select").clone();
|
||||
template.data("id", group.id);
|
||||
template.attr("grid", group.id);
|
||||
template.find(".ch_name").text(group.name);
|
||||
template.find('.group_fav_icon').css("display", 'none');
|
||||
template.addClass(group.fav ? 'is_fav' : '');
|
||||
template.find(".ch_fav").val(group.fav);
|
||||
|
||||
// Display inline tags
|
||||
const tags = getTagsList(group.id);
|
||||
const tagsElement = template.find('.tags');
|
||||
tags.forEach(tag => appendTagToList(tagsElement, tag, {}));
|
||||
// Display inline tags
|
||||
const tags = getTagsList(group.id);
|
||||
const tagsElement = template.find('.tags');
|
||||
tags.forEach(tag => appendTagToList(tagsElement, tag, {}));
|
||||
|
||||
const avatar = getGroupAvatar(group);
|
||||
if (avatar) {
|
||||
$(template).find(".avatar").replaceWith(avatar);
|
||||
}
|
||||
const avatar = getGroupAvatar(group);
|
||||
if (avatar) {
|
||||
$(template).find(".avatar").replaceWith(avatar);
|
||||
}
|
||||
|
||||
return template;
|
||||
return template;
|
||||
}
|
||||
|
||||
function updateGroupAvatar(group) {
|
||||
|
@ -360,17 +364,27 @@ function updateGroupAvatar(group) {
|
|||
|
||||
$(".group_select").each(function () {
|
||||
if ($(this).data("id") == group.id) {
|
||||
$(this).find(".avatar").replaceWith(getGroupAvatar(group));
|
||||
$(this).find(".avatar").replaceWith(getGroupAvatar(group));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// check if isDataURLor if it's a valid local file url
|
||||
function isValidImageUrl(url) {
|
||||
console.trace(url);
|
||||
// check if empty dict
|
||||
if (Object.keys(url).length === 0) {
|
||||
return false;
|
||||
}
|
||||
return isDataURL(url) || (url && url.startsWith("user"));
|
||||
}
|
||||
|
||||
function getGroupAvatar(group) {
|
||||
if (!group) {
|
||||
return $(`<div class="avatar"><img src="${default_avatar}"></div>`);
|
||||
}
|
||||
|
||||
if (isDataURL(group.avatar_url)) {
|
||||
// if isDataURL or if it's a valid local file url
|
||||
if (isValidImageUrl(group.avatar_url)) {
|
||||
return $(`<div class="avatar"><img src="${group.avatar_url}"></div>`);
|
||||
}
|
||||
|
||||
|
@ -1090,8 +1104,7 @@ function select_group_chats(groupId, skipAnimation) {
|
|||
|
||||
setMenuType(!!group ? 'group_edit' : 'group_create');
|
||||
$("#group_avatar_preview").empty().append(getGroupAvatar(group));
|
||||
$("#rm_group_restore_avatar").toggle(!!group && isDataURL(group.avatar_url));
|
||||
$("#rm_group_chat_name").val(groupName);
|
||||
$("#rm_group_restore_avatar").toggle(!!group && isValidImageUrl(group.avatar_url));
|
||||
$("#rm_group_filter").val("").trigger("input");
|
||||
$(`input[name="rm_group_activation_strategy"][value="${replyStrategy}"]`).prop('checked', true);
|
||||
|
||||
|
@ -1133,9 +1146,18 @@ function select_group_chats(groupId, skipAnimation) {
|
|||
$("#rm_group_automode_label").hide();
|
||||
}
|
||||
|
||||
eventSource.emit('groupSelected', {detail: {id: openGroupId, group: group}});
|
||||
eventSource.emit('groupSelected', { detail: { id: openGroupId, group: group } });
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the upload and processing of a group avatar.
|
||||
* The selected image is read, cropped using a popup, processed into a thumbnail,
|
||||
* and then uploaded to the server.
|
||||
*
|
||||
* @param {Event} event - The event triggered by selecting a file input, containing the image file to upload.
|
||||
*
|
||||
* @returns {Promise<void>} - A promise that resolves when the processing and upload is complete.
|
||||
*/
|
||||
async function uploadGroupAvatar(event) {
|
||||
const file = event.target.files[0];
|
||||
|
||||
|
@ -1158,16 +1180,22 @@ async function uploadGroupAvatar(event) {
|
|||
return;
|
||||
}
|
||||
|
||||
const thumbnail = await createThumbnail(croppedImage, 96, 144);
|
||||
|
||||
let thumbnail = await createThumbnail(croppedImage, 96, 144);
|
||||
//remove data:image/whatever;base64
|
||||
thumbnail = thumbnail.replace(/^data:image\/[a-z]+;base64,/, "");
|
||||
let _thisGroup = groups.find((x) => x.id == openGroupId);
|
||||
// filename should be group id + human readable timestamp
|
||||
const filename = `${_thisGroup.id}_${humanizedDateTime()}`;
|
||||
let thumbnailUrl = await saveBase64AsFile(thumbnail, openGroupId.toString(), filename, 'jpg');
|
||||
if (!openGroupId) {
|
||||
$('#group_avatar_preview img').attr('src', thumbnail);
|
||||
$('#group_avatar_preview img').attr('src', thumbnailUrl);
|
||||
$('#rm_group_restore_avatar').show();
|
||||
return;
|
||||
}
|
||||
|
||||
let _thisGroup = groups.find((x) => x.id == openGroupId);
|
||||
_thisGroup.avatar_url = thumbnail;
|
||||
|
||||
|
||||
_thisGroup.avatar_url = thumbnailUrl;
|
||||
$("#group_avatar_preview").empty().append(getGroupAvatar(_thisGroup));
|
||||
$("#rm_group_restore_avatar").show();
|
||||
await editGroup(openGroupId, true, true);
|
||||
|
@ -1248,8 +1276,11 @@ function updateFavButtonState(state) {
|
|||
$("#group_favorite_button").toggleClass('fav_off', !fav_grp_checked);
|
||||
}
|
||||
|
||||
async function selectGroup() {
|
||||
const groupId = $(this).data("id");
|
||||
export async function openGroupById(groupId) {
|
||||
if (!groups.find(x => x.id === groupId)) {
|
||||
console.log('Group not found', groupId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_send_press && !is_group_generating) {
|
||||
if (selected_group !== groupId) {
|
||||
|
@ -1290,16 +1321,8 @@ function openCharacterDefinition(characterSelect) {
|
|||
}
|
||||
|
||||
function filterGroupMembers() {
|
||||
const searchValue = $(this).val().trim().toLowerCase();
|
||||
|
||||
if (!searchValue) {
|
||||
$("#rm_group_add_members .group_member").removeClass('hiddenBySearch');
|
||||
} else {
|
||||
$("#rm_group_add_members .group_member").each(function () {
|
||||
const isValidSearch = $(this).find(".ch_name").text().toLowerCase().includes(searchValue);
|
||||
$(this).toggleClass('hiddenBySearch', !isValidSearch);
|
||||
});
|
||||
}
|
||||
const searchValue = $(this).val().toLowerCase();
|
||||
groupCandidatesFilter.setFilterData(FILTER_TYPES.SEARCH, searchValue);
|
||||
}
|
||||
|
||||
async function createGroup() {
|
||||
|
@ -1324,7 +1347,7 @@ async function createGroup() {
|
|||
body: JSON.stringify({
|
||||
name: name,
|
||||
members: members,
|
||||
avatar_url: isDataURL(avatar_url) ? avatar_url : default_avatar,
|
||||
avatar_url: isValidImageUrl(avatar_url) ? avatar_url : default_avatar,
|
||||
allow_self_responses: allow_self_responses,
|
||||
activation_strategy: activation_strategy,
|
||||
disabled_members: [],
|
||||
|
@ -1570,7 +1593,10 @@ function doCurMemberListPopout() {
|
|||
}
|
||||
|
||||
jQuery(() => {
|
||||
$(document).on("click", ".group_select", selectGroup);
|
||||
$(document).on("click", ".group_select", function () {
|
||||
const groupId = $(this).data("id");
|
||||
openGroupById(groupId);
|
||||
});
|
||||
$("#rm_group_filter").on("input", filterGroupMembers);
|
||||
$("#rm_group_submit").on("click", createGroup);
|
||||
$("#rm_group_scenario").on("click", setScenarioOverride);
|
||||
|
|
|
@ -578,7 +578,7 @@ function calculateLogitBias() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Transforms instruction into compatible format for Novel AI.
|
||||
* Transforms instruction into compatible format for Novel AI if Novel AI instruct format not already detected.
|
||||
* 1. Instruction must begin and end with curly braces followed and preceded by a space.
|
||||
* 2. Instruction must not contain square brackets as it serves different purpose in NAI.
|
||||
* @param {string} prompt Original instruction prompt
|
||||
|
@ -586,7 +586,10 @@ function calculateLogitBias() {
|
|||
*/
|
||||
export function adjustNovelInstructionPrompt(prompt) {
|
||||
const stripedPrompt = prompt.replace(/[\[\]]/g, '').trim();
|
||||
return `{ ${stripedPrompt} }`;
|
||||
if (!stripedPrompt.includes('{ ')) {
|
||||
return `{ ${stripedPrompt} }`;
|
||||
}
|
||||
return stripedPrompt;
|
||||
}
|
||||
|
||||
export async function generateNovelWithStreaming(generate_data, signal) {
|
||||
|
|
|
@ -19,7 +19,6 @@ import {
|
|||
system_message_types,
|
||||
replaceBiasMarkup,
|
||||
is_send_press,
|
||||
saveSettings,
|
||||
Generate,
|
||||
main_api,
|
||||
eventSource,
|
||||
|
@ -45,6 +44,7 @@ import {
|
|||
} from "./secrets.js";
|
||||
|
||||
import {
|
||||
deepClone,
|
||||
delay,
|
||||
download,
|
||||
getFileText, getSortableDelay,
|
||||
|
@ -390,7 +390,7 @@ function setupChatCompletionPromptManager(openAiSettings) {
|
|||
promptManager.tokenHandler = tokenHandler;
|
||||
|
||||
promptManager.init(configuration, openAiSettings);
|
||||
promptManager.render();
|
||||
promptManager.render(false);
|
||||
|
||||
return promptManager;
|
||||
}
|
||||
|
@ -480,11 +480,19 @@ function populateChatHistory(prompts, chatCompletion, type = null, cyclePrompt =
|
|||
// Chat History
|
||||
chatCompletion.add(new MessageCollection('chatHistory'), prompts.index('chatHistory'));
|
||||
|
||||
let names = (selected_group && groups.find(x => x.id === selected_group)?.members.map(member => characters.find(c => c.avatar === member)?.name).filter(Boolean).join(', ')) || '';
|
||||
// Reserve budget for new chat message
|
||||
const newChat = selected_group ? oai_settings.new_group_chat_prompt : oai_settings.new_chat_prompt;
|
||||
const newChatMessage = new Message('system', newChat, 'newMainChat');
|
||||
const newChatMessage = new Message('system', substituteParams(newChat, null, null, null, names), 'newMainChat');
|
||||
chatCompletion.reserveBudget(newChatMessage);
|
||||
|
||||
// Reserve budget for group nudge
|
||||
let groupNudgeMessage = null;
|
||||
if(selected_group) {
|
||||
const groupNudgeMessage = new Message.fromPrompt(prompts.get('groupNudge'));
|
||||
chatCompletion.reserveBudget(groupNudgeMessage);
|
||||
}
|
||||
|
||||
// Reserve budget for continue nudge
|
||||
let continueMessage = null;
|
||||
if (type === 'continue' && cyclePrompt) {
|
||||
|
@ -513,7 +521,8 @@ function populateChatHistory(prompts, chatCompletion, type = null, cyclePrompt =
|
|||
const chatMessage = Message.fromPrompt(promptManager.preparePrompt(prompt));
|
||||
|
||||
if (true === promptManager.serviceSettings.names_in_completion && prompt.name) {
|
||||
chatMessage.name = promptManager.isValidName(prompt.name) ? prompt.name : promptManager.sanitizeName(prompt.name);
|
||||
const messageName = promptManager.isValidName(prompt.name) ? prompt.name : promptManager.sanitizeName(prompt.name);
|
||||
chatMessage.setName(messageName);
|
||||
}
|
||||
|
||||
if (chatCompletion.canAfford(chatMessage)) chatCompletion.insertAtStart(chatMessage, 'chatHistory');
|
||||
|
@ -525,6 +534,12 @@ function populateChatHistory(prompts, chatCompletion, type = null, cyclePrompt =
|
|||
chatCompletion.freeBudget(newChatMessage);
|
||||
chatCompletion.insertAtStart(newChatMessage, 'chatHistory');
|
||||
|
||||
// Reserve budget for group nudge
|
||||
if(selected_group && groupNudgeMessage) {
|
||||
chatCompletion.freeBudget(groupNudgeMessage);
|
||||
chatCompletion.insertAtEnd(groupNudgeMessage, 'chatHistory');
|
||||
}
|
||||
|
||||
// Insert and free continue nudge
|
||||
if (type === 'continue' && continueMessage) {
|
||||
chatCompletion.freeBudget(continueMessage);
|
||||
|
@ -542,9 +557,11 @@ function populateDialogueExamples(prompts, chatCompletion) {
|
|||
chatCompletion.add(new MessageCollection('dialogueExamples'), prompts.index('dialogueExamples'));
|
||||
if (openai_msgs_example.length) {
|
||||
const newExampleChat = new Message('system', oai_settings.new_example_chat_prompt, 'newChat');
|
||||
chatCompletion.reserveBudget(newExampleChat);
|
||||
|
||||
[...openai_msgs_example].forEach((dialogue, dialogueIndex) => {
|
||||
let examplesAdded = 0;
|
||||
|
||||
if (chatCompletion.canAfford(newExampleChat)) chatCompletion.insert(newExampleChat, 'dialogueExamples');
|
||||
|
||||
dialogue.forEach((prompt, promptIndex) => {
|
||||
const role = 'system';
|
||||
const content = prompt.content || '';
|
||||
|
@ -554,14 +571,14 @@ function populateDialogueExamples(prompts, chatCompletion) {
|
|||
chatMessage.setName(prompt.name);
|
||||
if (chatCompletion.canAfford(chatMessage)) {
|
||||
chatCompletion.insert(chatMessage, 'dialogueExamples');
|
||||
examplesAdded++;
|
||||
}
|
||||
});
|
||||
|
||||
if (0 === examplesAdded) {
|
||||
chatCompletion.removeLastFrom('dialogueExamples');
|
||||
}
|
||||
});
|
||||
|
||||
chatCompletion.freeBudget(newExampleChat);
|
||||
|
||||
const chatExamples = chatCompletion.getMessages().getItemByIdentifier('dialogueExamples').getCollection();
|
||||
if (chatExamples.length) chatCompletion.insertAtStart(newExampleChat, 'dialogueExamples');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -700,9 +717,10 @@ function populateChatCompletion(prompts, chatCompletion, { bias, quietPrompt, ty
|
|||
*
|
||||
* @returns {Object} prompts - The prepared and merged system and user-defined prompts.
|
||||
*/
|
||||
function preparePromptsForChatCompletion(Scenario, charPersonality, name2, worldInfoBefore, worldInfoAfter, charDescription, quietPrompt, bias, extensionPrompts) {
|
||||
function preparePromptsForChatCompletion(Scenario, charPersonality, name2, worldInfoBefore, worldInfoAfter, charDescription, quietPrompt, bias, extensionPrompts, systemPromptOverride, jailbreakPromptOverride) {
|
||||
const scenarioText = Scenario ? `[Circumstances and context of the dialogue: ${Scenario}]` : '';
|
||||
const charPersonalityText = charPersonality ? `[${name2}'s personality: ${charPersonality}]` : '';
|
||||
const charPersonalityText = charPersonality ? `[${name2}'s personality: ${charPersonality}]` : ''
|
||||
const groupNudge = `[Write the next reply only as ${name2}]`;
|
||||
|
||||
// Create entries for system prompts
|
||||
const systemPrompts = [
|
||||
|
@ -716,7 +734,8 @@ function preparePromptsForChatCompletion(Scenario, charPersonality, name2, world
|
|||
{ role: 'system', content: oai_settings.nsfw_avoidance_prompt, identifier: 'nsfwAvoidance' },
|
||||
{ role: 'system', content: oai_settings.impersonation_prompt, identifier: 'impersonate' },
|
||||
{ role: 'system', content: quietPrompt, identifier: 'quietPrompt' },
|
||||
{ role: 'system', content: bias, identifier: 'bias' }
|
||||
{ role: 'system', content: bias, identifier: 'bias' },
|
||||
{ role: 'system', content: groupNudge, identifier: 'groupNudge' }
|
||||
];
|
||||
|
||||
// Tavern Extras - Summary
|
||||
|
@ -753,7 +772,6 @@ function preparePromptsForChatCompletion(Scenario, charPersonality, name2, world
|
|||
});
|
||||
|
||||
// Apply character-specific main prompt
|
||||
const systemPromptOverride = promptManager.activeCharacter.data?.system_prompt ?? null;
|
||||
const systemPrompt = prompts.get('main') ?? null;
|
||||
if (systemPromptOverride && systemPrompt) {
|
||||
const mainOriginalContent = systemPrompt.content;
|
||||
|
@ -763,7 +781,6 @@ function preparePromptsForChatCompletion(Scenario, charPersonality, name2, world
|
|||
}
|
||||
|
||||
// Apply character-specific jailbreak
|
||||
const jailbreakPromptOverride = promptManager.activeCharacter.data?.post_history_instructions ?? null;
|
||||
const jailbreakPrompt = prompts.get('jailbreak') ?? null;
|
||||
if (jailbreakPromptOverride && jailbreakPrompt) {
|
||||
const jbOriginalContent = jailbreakPrompt.content;
|
||||
|
@ -807,7 +824,9 @@ function prepareOpenAIMessages({
|
|||
type,
|
||||
quietPrompt,
|
||||
extensionPrompts,
|
||||
cyclePrompt
|
||||
cyclePrompt,
|
||||
systemPromptOverride,
|
||||
jailbreakPromptOverride,
|
||||
} = {}, dryRun) {
|
||||
// Without a character selected, there is no way to accurately calculate tokens
|
||||
if (!promptManager.activeCharacter && dryRun) return [null, false];
|
||||
|
@ -820,7 +839,7 @@ function prepareOpenAIMessages({
|
|||
|
||||
try {
|
||||
// Merge markers and ordered user prompts with system prompts
|
||||
const prompts = preparePromptsForChatCompletion(Scenario, charPersonality, name2, worldInfoBefore, worldInfoAfter, charDescription, quietPrompt, bias, extensionPrompts);
|
||||
const prompts = preparePromptsForChatCompletion(Scenario, charPersonality, name2, worldInfoBefore, worldInfoAfter, charDescription, quietPrompt, bias, extensionPrompts, systemPromptOverride, jailbreakPromptOverride);
|
||||
|
||||
// Fill the chat completion with as much context as the budget allows
|
||||
populateChatCompletion(prompts, chatCompletion, { bias, quietPrompt, type, cyclePrompt });
|
||||
|
@ -1371,7 +1390,7 @@ function countTokens(messages, full = false) {
|
|||
|
||||
for (const message of messages) {
|
||||
const model = getTokenizerModel();
|
||||
const hash = getStringHash(message.content);
|
||||
const hash = getStringHash(JSON.stringify(message));
|
||||
const cacheKey = `${model}-${hash}`;
|
||||
const cachedCount = tokenCache[chatId][cacheKey];
|
||||
|
||||
|
@ -1443,8 +1462,8 @@ class Message {
|
|||
this.role = role;
|
||||
this.content = content;
|
||||
|
||||
if (this.content) {
|
||||
this.tokens = tokenHandler.count({ role: this.role, content: this.content })
|
||||
if (typeof this.content === 'string') {
|
||||
this.tokens = tokenHandler.count({ role: this.role, content: this.content });
|
||||
} else {
|
||||
this.tokens = 0;
|
||||
}
|
||||
|
@ -1452,6 +1471,7 @@ class Message {
|
|||
|
||||
setName(name) {
|
||||
this.name = name;
|
||||
this.tokens = tokenHandler.count({ role: this.role, content: this.content, name: this.name });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1663,6 +1683,21 @@ class ChatCompletion {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the last item of the collection
|
||||
*
|
||||
* @param identifier
|
||||
*/
|
||||
removeLastFrom(identifier) {
|
||||
const index = this.findMessageIndex(identifier);
|
||||
const message = this.messages.collection[index].collection.pop();
|
||||
|
||||
this.increaseTokenBudgetBy(message.getTokens());
|
||||
|
||||
this.log(`Removed ${message.identifier} from ${identifier}. Remaining tokens: ${this.tokenBudget}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the token budget can afford the tokens of the specified message.
|
||||
*
|
||||
|
@ -2349,7 +2384,11 @@ async function onExportPresetClick() {
|
|||
return;
|
||||
}
|
||||
|
||||
const preset = openai_settings[openai_setting_names[oai_settings.preset_settings_openai]];
|
||||
const preset = deepClone(openai_settings[openai_setting_names[oai_settings.preset_settings_openai]]);
|
||||
|
||||
delete preset.reverse_proxy;
|
||||
delete preset.proxy_password;
|
||||
|
||||
const presetJsonString = JSON.stringify(preset, null, 4);
|
||||
download(presetJsonString, oai_settings.preset_settings_openai, 'application/json');
|
||||
}
|
||||
|
|
|
@ -285,8 +285,8 @@ function appendTagToList(listElement, tag, { removable, selectable, action, isGe
|
|||
tagElement.find('.tag_name').text('').attr('title', tag.name).addClass(tag.icon);
|
||||
}
|
||||
|
||||
if (tag.excluded) {
|
||||
isGeneralList ? $(tagElement).addClass('excluded') : $(listElement).closest('.character_select, .group_select').addClass('hiddenByTag');
|
||||
if (tag.excluded && isGeneralList) {
|
||||
$(tagElement).addClass('excluded');
|
||||
}
|
||||
|
||||
if (selectable) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { getContext } from "./extensions.js";
|
||||
import { getRequestHeaders } from "../script.js";
|
||||
|
||||
export function onlyUnique(value, index, array) {
|
||||
return array.indexOf(value) === index;
|
||||
|
@ -554,6 +555,48 @@ export function extractDataFromPng(data, identifier = 'chara') {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a base64 encoded image to the backend to be saved as a file.
|
||||
*
|
||||
* @param {string} base64Data - The base64 encoded image data.
|
||||
* @param {string} characterName - The character name to determine the sub-directory for saving.
|
||||
* @param {string} ext - The file extension for the image (e.g., 'jpg', 'png', 'webp').
|
||||
*
|
||||
* @returns {Promise<string>} - Resolves to the saved image's path on the server.
|
||||
* Rejects with an error if the upload fails.
|
||||
*/
|
||||
export async function saveBase64AsFile(base64Data, characterName, filename = "", ext) {
|
||||
// Construct the full data URL
|
||||
const format = ext; // Extract the file extension (jpg, png, webp)
|
||||
const dataURL = `data:image/${format};base64,${base64Data}`;
|
||||
|
||||
// Prepare the request body
|
||||
const requestBody = {
|
||||
image: dataURL,
|
||||
ch_name: characterName,
|
||||
filename: filename
|
||||
};
|
||||
|
||||
// Send the data URL to your backend using fetch
|
||||
const response = await fetch('/uploadimage', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(requestBody),
|
||||
headers: {
|
||||
...getRequestHeaders(),
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
});
|
||||
|
||||
// If the response is successful, get the saved image path from the server's response
|
||||
if (response.ok) {
|
||||
const responseData = await response.json();
|
||||
return responseData.path;
|
||||
} else {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData.error || 'Failed to upload the image to the server');
|
||||
}
|
||||
}
|
||||
|
||||
export function createThumbnail(dataUrl, maxWidth, maxHeight) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
|
|
|
@ -464,7 +464,7 @@ function appendWorldEntry(name, data, entry) {
|
|||
|
||||
const contentInput = template.find('textarea[name="content"]');
|
||||
contentInput.data("uid", entry.uid);
|
||||
contentInput.on("input", function () {
|
||||
contentInput.on("input", function (_, { skipCount } = {}) {
|
||||
const uid = $(this).data("uid");
|
||||
const value = $(this).val();
|
||||
data.entries[uid].content = value;
|
||||
|
@ -472,12 +472,25 @@ function appendWorldEntry(name, data, entry) {
|
|||
setOriginalDataValue(data, uid, "content", data.entries[uid].content);
|
||||
saveWorldInfo(name, data);
|
||||
|
||||
if (skipCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
// count tokens
|
||||
countTokensDebounced(this, value);
|
||||
});
|
||||
contentInput.val(entry.content).trigger("input");
|
||||
contentInput.val(entry.content).trigger("input", { skipCount: true });
|
||||
//initScrollHeight(contentInput);
|
||||
|
||||
template.find('.inline-drawer-toggle').on('click', function () {
|
||||
const counter = template.find(".world_entry_form_token_counter");
|
||||
|
||||
if (counter.data('first-run')) {
|
||||
counter.data('first-run', false);
|
||||
countTokensDebounced(contentInput, contentInput.val());
|
||||
}
|
||||
});
|
||||
|
||||
// selective
|
||||
const selectiveInput = template.find('input[name="selective"]');
|
||||
selectiveInput.data("uid", entry.uid);
|
||||
|
|
2199
public/style.css
2199
public/style.css
File diff suppressed because it is too large
Load Diff
77
server.js
77
server.js
|
@ -297,6 +297,8 @@ const baseRequestArgs = { headers: { "Content-Type": "application/json" } };
|
|||
const directories = {
|
||||
worlds: 'public/worlds/',
|
||||
avatars: 'public/User Avatars',
|
||||
images: 'public/img/',
|
||||
userImages: 'public/user/images/',
|
||||
groups: 'public/groups/',
|
||||
groupChats: 'public/group chats',
|
||||
chats: 'public/chats/',
|
||||
|
@ -599,7 +601,7 @@ app.post("/generate_textgenerationwebui", jsonParser, async function (request, r
|
|||
});
|
||||
|
||||
async function* readWebsocket() {
|
||||
const streamingUrl = request.header('X-Streaming-URL');
|
||||
const streamingUrl = request.header('X-Streaming-URL').replace("localhost", "127.0.0.1");
|
||||
const websocket = new WebSocket(streamingUrl);
|
||||
|
||||
websocket.on('open', async function () {
|
||||
|
@ -2611,6 +2613,73 @@ app.post('/uploaduseravatar', urlencodedParser, async (request, response) => {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Ensure the directory for the provided file path exists.
|
||||
* If not, it will recursively create the directory.
|
||||
*
|
||||
* @param {string} filePath - The full path of the file for which the directory should be ensured.
|
||||
*/
|
||||
function ensureDirectoryExistence(filePath) {
|
||||
const dirname = path.dirname(filePath);
|
||||
if (fs.existsSync(dirname)) {
|
||||
return true;
|
||||
}
|
||||
ensureDirectoryExistence(dirname);
|
||||
fs.mkdirSync(dirname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Endpoint to handle image uploads.
|
||||
* The image should be provided in the request body in base64 format.
|
||||
* Optionally, a character name can be provided to save the image in a sub-folder.
|
||||
*
|
||||
* @route POST /uploadimage
|
||||
* @param {Object} request.body - The request payload.
|
||||
* @param {string} request.body.image - The base64 encoded image data.
|
||||
* @param {string} [request.body.ch_name] - Optional character name to determine the sub-directory.
|
||||
* @returns {Object} response - The response object containing the path where the image was saved.
|
||||
*/
|
||||
app.post('/uploadimage', jsonParser, async (request, response) => {
|
||||
// Check for image data
|
||||
if (!request.body || !request.body.image) {
|
||||
return response.status(400).send({ error: "No image data provided" });
|
||||
}
|
||||
|
||||
// Extracting the base64 data and the image format
|
||||
const match = request.body.image.match(/^data:image\/(png|jpg|webp);base64,(.+)$/);
|
||||
if (!match) {
|
||||
return response.status(400).send({ error: "Invalid image format" });
|
||||
}
|
||||
|
||||
const [, format, base64Data] = match;
|
||||
|
||||
// Constructing filename and path
|
||||
let filename = `${Date.now()}.${format}`;
|
||||
if (request.body.filename) {
|
||||
filename = `${request.body.filename}.${format}`;
|
||||
}
|
||||
|
||||
// if character is defined, save to a sub folder for that character
|
||||
let pathToNewFile = path.join(directories.userImages, filename);
|
||||
if (request.body.ch_name) {
|
||||
pathToNewFile = path.join(directories.userImages, request.body.ch_name, filename);
|
||||
}
|
||||
|
||||
try {
|
||||
ensureDirectoryExistence(pathToNewFile);
|
||||
const imageBuffer = Buffer.from(base64Data, 'base64');
|
||||
await fs.promises.writeFile(pathToNewFile, imageBuffer);
|
||||
// send the path to the image, relative to the client folder, which means removing the first folder from the path which is 'public'
|
||||
pathToNewFile = pathToNewFile.split(path.sep).slice(1).join(path.sep);
|
||||
response.send({ path: pathToNewFile });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
response.status(500).send({ error: "Failed to save the image" });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
app.post('/getgroups', jsonParser, (_, response) => {
|
||||
const groups = [];
|
||||
|
||||
|
@ -2659,7 +2728,7 @@ app.post('/creategroup', jsonParser, (request, response) => {
|
|||
return response.sendStatus(400);
|
||||
}
|
||||
|
||||
const id = Date.now();
|
||||
const id = String(Date.now());
|
||||
const groupMetadata = {
|
||||
id: id,
|
||||
name: request.body.name ?? 'New Group',
|
||||
|
@ -3391,7 +3460,7 @@ app.post("/generate_openai", jsonParser, function (request, response_generate_op
|
|||
config.responseType = 'stream';
|
||||
}
|
||||
|
||||
async function makeRequest(config, response_generate_openai, request, retries = 5, timeout = 1000) {
|
||||
async function makeRequest(config, response_generate_openai, request, retries = 5, timeout = 5000) {
|
||||
try {
|
||||
const response = await axios(config);
|
||||
|
||||
|
@ -3413,7 +3482,7 @@ app.post("/generate_openai", jsonParser, function (request, response_generate_op
|
|||
}
|
||||
} catch (error) {
|
||||
if (error.response && error.response.status === 429 && retries > 0) {
|
||||
console.log('Out of quota, retrying...');
|
||||
console.log(`Out of quota, retrying in ${Math.round(timeout / 1000)}s`);
|
||||
setTimeout(() => {
|
||||
makeRequest(config, response_generate_openai, request, retries - 1);
|
||||
}, timeout);
|
||||
|
|
Loading…
Reference in New Issue