Merge branch 'staging' into anachronous/release

This commit is contained in:
Cohee 2023-12-17 21:35:49 +02:00
commit 180061337e
8 changed files with 88 additions and 12 deletions

View File

@ -54,6 +54,10 @@ extras:
openai:
# Will send a random user ID to OpenAI completion API
randomizeUserId: false
# If not empty, will add this as a system message to the start of every caption completion prompt
# Example: "Perform the instructions to the best of your ability.\n\n" (for LLaVA)
# Not used in image inlining mode
captionSystemPrompt: ""
# -- DEEPL TRANSLATION CONFIGURATION --
deepl:
# Available options: default, more, less, prefer_more, prefer_less

View File

@ -291,6 +291,7 @@ export const event_types = {
MESSAGE_DELETED: 'message_deleted',
IMPERSONATE_READY: 'impersonate_ready',
CHAT_CHANGED: 'chat_id_changed',
GENERATION_STARTED: 'generation_started',
GENERATION_STOPPED: 'generation_stopped',
EXTENSIONS_FIRST_LOAD: 'extensions_first_load',
SETTINGS_LOADED: 'settings_loaded',
@ -2925,6 +2926,7 @@ export async function generateRaw(prompt, api, instructOverride) {
// Returns a promise that resolves when the text is done generating.
async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, maxLoops } = {}, dryRun = false) {
console.log('Generate entered');
eventSource.emit(event_types.GENERATION_STARTED, type, { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, maxLoops }, dryRun);
setGenerationProgress(0);
generation_started = new Date();

View File

@ -18,6 +18,7 @@ import {
eventSource,
menu_type,
substituteParams,
callPopup,
} from '../script.js';
import {
@ -996,9 +997,31 @@ export function initRossMods() {
console.debug('Accepting edits with Ctrl+Enter');
editMesDone.trigger('click');
} else if (is_send_press == false) {
console.debug('Regenerating with Ctrl+Enter');
$('#option_regenerate').click();
$('#options').hide();
const skipConfirmKey = 'RegenerateWithCtrlEnter';
const skipConfirm = LoadLocalBool(skipConfirmKey);
function doRegenerate() {
console.debug('Regenerating with Ctrl+Enter');
$('#option_regenerate').trigger('click');
$('#options').hide();
}
if (skipConfirm) {
doRegenerate();
} else {
const popupText = `
<div class="marginBot10">Are you sure you want to regenerate the latest message?</div>
<label class="checkbox_label justifyCenter" for="regenerateWithCtrlEnter">
<input type="checkbox" id="regenerateWithCtrlEnter">
Don't ask again
</label>`;
callPopup(popupText, 'confirm').then(result =>{
if (!result) {
return;
}
const regenerateWithCtrlEnter = $('#regenerateWithCtrlEnter').prop('checked');
SaveLocal(skipConfirmKey, regenerateWithCtrlEnter);
doRegenerate();
});
}
} else {
console.debug('Ctrl+Enter ignored');
}
@ -1054,11 +1077,12 @@ export function initRossMods() {
}
if (event.key == 'ArrowUp') { //edits last message if chatbar is empty and focused
//console.log('got uparrow input');
console.log('got uparrow input');
if (
$('#send_textarea').val() === '' &&
chatbarInFocus === true &&
$('.swipe_right:last').css('display') === 'flex' &&
//$('.swipe_right:last').css('display') === 'flex' &&
$('.last_mes .mes_buttons').is(':visible') &&
$('#character_popup').css('display') === 'none' &&
$('#shadow_select_chat_popup').css('display') === 'none'
) {

View File

@ -237,6 +237,12 @@ async function convertSoloToGroupChat() {
return;
}
const confirm = await callPopup('Are you sure you want to convert this chat to a group chat?', 'confirm');
if (!confirm) {
return;
}
const character = characters[this_chid];
// Populate group required fields

View File

@ -300,7 +300,7 @@ jQuery(function () {
$('#caption_prompt_block').toggle(isMultimodal);
$('#caption_multimodal_api').val(extension_settings.caption.multimodal_api);
$('#caption_multimodal_model').val(extension_settings.caption.multimodal_model);
$('#caption_multimodal_model option').each(function () {
$('#caption_multimodal_block [data-type]').each(function () {
const type = $(this).data('type');
$(this).toggle(type === extension_settings.caption.multimodal_api);
});
@ -351,6 +351,10 @@ jQuery(function () {
<option data-type="openrouter" value="haotian-liu/llava-13b">haotian-liu/llava-13b</option>
</select>
</div>
<label data-type="openai" class="checkbox_label flexBasis100p" for="caption_allow_reverse_proxy" title="Allow using reverse proxy if defined and valid.">
<input id="caption_allow_reverse_proxy" type="checkbox" class="checkbox">
Allow reverse proxy
</label>
</div>
<div id="caption_prompt_block">
<label for="caption_prompt">Caption Prompt</label>
@ -377,6 +381,7 @@ jQuery(function () {
switchMultimodalBlocks();
$('#caption_refine_mode').prop('checked', !!(extension_settings.caption.refine_mode));
$('#caption_allow_reverse_proxy').prop('checked', !!(extension_settings.caption.allow_reverse_proxy));
$('#caption_source').val(extension_settings.caption.source);
$('#caption_prompt').val(extension_settings.caption.prompt);
$('#caption_template').val(extension_settings.caption.template);
@ -394,4 +399,8 @@ jQuery(function () {
extension_settings.caption.template = String($('#caption_template').val());
saveSettingsDebounced();
});
$('#caption_allow_reverse_proxy').on('input', () => {
extension_settings.caption.allow_reverse_proxy = $('#caption_allow_reverse_proxy').prop('checked');
saveSettingsDebounced();
});
});

View File

@ -1,7 +1,8 @@
import { getRequestHeaders } from '../../script.js';
import { extension_settings } from '../extensions.js';
import { oai_settings } from '../openai.js';
import { SECRET_KEYS, secret_state } from '../secrets.js';
import { createThumbnail } from '../utils.js';
import { createThumbnail, isValidUrl } from '../utils.js';
/**
* Generates a caption for an image using a multimodal model.
@ -35,6 +36,15 @@ export async function getMultimodalCaption(base64Img, prompt) {
}
}
const useReverseProxy =
extension_settings.caption.multimodal_api === 'openai'
&& extension_settings.caption.allow_reverse_proxy
&& oai_settings.reverse_proxy
&& isValidUrl(oai_settings.reverse_proxy);
const proxyUrl = useReverseProxy ? oai_settings.reverse_proxy : '';
const proxyPassword = useReverseProxy ? oai_settings.proxy_password : '';
const apiResult = await fetch(`/api/${isGoogle ? 'google' : 'openai'}/caption-image`, {
method: 'POST',
headers: getRequestHeaders(),
@ -46,6 +56,8 @@ export async function getMultimodalCaption(base64Img, prompt) {
: {
api: extension_settings.caption.multimodal_api || 'openai',
model: extension_settings.caption.multimodal_model || 'gpt-4-vision-preview',
reverse_proxy: proxyUrl,
proxy_password: proxyPassword,
}),
}),
});

View File

@ -323,7 +323,7 @@ class PresetManager {
}
async deleteCurrentPreset() {
const { preset_names } = this.getPresetList();
const { preset_names, presets } = this.getPresetList();
const value = this.getSelectedPreset();
const nameToDelete = this.getSelectedPresetName();
@ -335,7 +335,9 @@ class PresetManager {
$(this.select).find(`option[value="${value}"]`).remove();
if (this.isKeyedApi()) {
preset_names.splice(preset_names.indexOf(value), 1);
const index = preset_names.indexOf(nameToDelete);
preset_names.splice(index, 1);
presets.splice(index, 1);
} else {
delete preset_names[nameToDelete];
}

View File

@ -4,6 +4,7 @@ const express = require('express');
const FormData = require('form-data');
const fs = require('fs');
const { jsonParser, urlencodedParser } = require('../express-common');
const { getConfigValue } = require('../util');
const router = express.Router();
@ -11,15 +12,19 @@ router.post('/caption-image', jsonParser, async (request, response) => {
try {
let key = '';
if (request.body.api === 'openai') {
if (request.body.api === 'openai' && !request.body.reverse_proxy) {
key = readSecret(SECRET_KEYS.OPENAI);
}
if (request.body.api === 'openrouter') {
if (request.body.api === 'openrouter' && !request.body.reverse_proxy) {
key = readSecret(SECRET_KEYS.OPENROUTER);
}
if (!key) {
if (request.body.reverse_proxy && request.body.proxy_password) {
key = request.body.proxy_password;
}
if (!key && !request.body.reverse_proxy) {
console.log('No key found for API', request.body.api);
return response.sendStatus(400);
}
@ -38,6 +43,14 @@ router.post('/caption-image', jsonParser, async (request, response) => {
max_tokens: 500,
};
const captionSystemPrompt = getConfigValue('openai.captionSystemPrompt');
if (captionSystemPrompt) {
body.messages.unshift({
role: 'system',
content: captionSystemPrompt,
});
}
console.log('Multimodal captioning request', body);
let apiUrl = '';
@ -52,6 +65,10 @@ router.post('/caption-image', jsonParser, async (request, response) => {
apiUrl = 'https://api.openai.com/v1/chat/completions';
}
if (request.body.reverse_proxy) {
apiUrl = `${request.body.reverse_proxy}/chat/completions`;
}
const result = await fetch(apiUrl, {
method: 'POST',
headers: {