Add prompt format override for OpenRouter
This commit is contained in:
parent
814c62cc21
commit
f10833a516
|
@ -1941,12 +1941,24 @@
|
||||||
<input id="openrouter_use_fallback" type="checkbox" />
|
<input id="openrouter_use_fallback" type="checkbox" />
|
||||||
<span data-i18n="Allow fallback routes">Allow fallback routes</span>
|
<span data-i18n="Allow fallback routes">Allow fallback routes</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="toggle-description justifyLeft">
|
<div class="toggle-description justifyLeft wide100p">
|
||||||
<span data-i18n="Allow fallback routes Description">
|
<span data-i18n="Allow fallback routes Description">
|
||||||
Automatically chooses an alternative model if the chosen model can't serve your request.
|
Automatically chooses an alternative model if the chosen model can't serve your request.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="marginTopBot5">
|
||||||
|
<label for="openrouter_force_instruct" class="checkbox_label">
|
||||||
|
<input id="openrouter_force_instruct" type="checkbox" />
|
||||||
|
<span data-i18n="Force Instruct Mode formatting">Force Instruct Mode formatting</span>
|
||||||
|
</label>
|
||||||
|
<div class="toggle-description justifyLeft wide100p">
|
||||||
|
<span data-i18n="Force Instruct Mode formatting Description">
|
||||||
|
If both Instruct Mode and this are enabled, the prompt will be formatted by SillyTavern using the current
|
||||||
|
advanced formatting settings (except instruct System Prompt). If disabled, the prompt will be formatted by OpenRouter.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<h4 data-i18n="OpenRouter API Key">OpenRouter API Key</h4>
|
<h4 data-i18n="OpenRouter API Key">OpenRouter API Key</h4>
|
||||||
<div>
|
<div>
|
||||||
<small data-i18n="Click Authorize below or get the key from">
|
<small data-i18n="Click Authorize below or get the key from">
|
||||||
|
|
|
@ -55,6 +55,7 @@ import {
|
||||||
stringFormat,
|
stringFormat,
|
||||||
} from "./utils.js";
|
} from "./utils.js";
|
||||||
import { countTokensOpenAI } from "./tokenizers.js";
|
import { countTokensOpenAI } from "./tokenizers.js";
|
||||||
|
import { formatInstructModeChat, formatInstructModeExamples, formatInstructModePrompt, formatInstructModeSystemPrompt } from "./instruct-mode.js";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
is_get_status_openai,
|
is_get_status_openai,
|
||||||
|
@ -205,6 +206,7 @@ const default_settings = {
|
||||||
windowai_model: '',
|
windowai_model: '',
|
||||||
openrouter_model: openrouter_website_model,
|
openrouter_model: openrouter_website_model,
|
||||||
openrouter_use_fallback: false,
|
openrouter_use_fallback: false,
|
||||||
|
openrouter_force_instruct: false,
|
||||||
jailbreak_system: false,
|
jailbreak_system: false,
|
||||||
reverse_proxy: '',
|
reverse_proxy: '',
|
||||||
legacy_streaming: false,
|
legacy_streaming: false,
|
||||||
|
@ -250,6 +252,7 @@ const oai_settings = {
|
||||||
windowai_model: '',
|
windowai_model: '',
|
||||||
openrouter_model: openrouter_website_model,
|
openrouter_model: openrouter_website_model,
|
||||||
openrouter_use_fallback: false,
|
openrouter_use_fallback: false,
|
||||||
|
openrouter_force_instruct: false,
|
||||||
jailbreak_system: false,
|
jailbreak_system: false,
|
||||||
reverse_proxy: '',
|
reverse_proxy: '',
|
||||||
legacy_streaming: false,
|
legacy_streaming: false,
|
||||||
|
@ -291,6 +294,90 @@ function setOpenAIOnlineStatus(value) {
|
||||||
is_get_status_openai = value;
|
is_get_status_openai = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function convertChatCompletionToInstruct(messages, type) {
|
||||||
|
messages = messages.filter(x => x.content !== oai_settings.new_chat_prompt && x.content !== oai_settings.new_example_chat_prompt);
|
||||||
|
|
||||||
|
let chatMessagesText = '';
|
||||||
|
let systemPromptText = '';
|
||||||
|
let examplesText = '';
|
||||||
|
|
||||||
|
function getPrefix(message) {
|
||||||
|
let prefix;
|
||||||
|
|
||||||
|
if (message.role === 'user' || message.name === 'example_user') {
|
||||||
|
if (selected_group) {
|
||||||
|
prefix = ''
|
||||||
|
} else if (message.name === 'example_user') {
|
||||||
|
prefix = name1;
|
||||||
|
} else {
|
||||||
|
prefix = message.name ?? name1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.role === 'assistant' || message.name === 'example_assistant') {
|
||||||
|
if (selected_group) {
|
||||||
|
prefix = ''
|
||||||
|
}
|
||||||
|
else if (message.name === 'example_assistant') {
|
||||||
|
prefix = name2;
|
||||||
|
} else {
|
||||||
|
prefix = message.name ?? name2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toString(message) {
|
||||||
|
if (message.role === 'system' && !message.name) {
|
||||||
|
return message.content;
|
||||||
|
}
|
||||||
|
|
||||||
|
const prefix = getPrefix(message);
|
||||||
|
return prefix ? `${prefix}: ${message.content}` : message.content;
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstChatMessage = messages.findIndex(message => message.role === 'assistant' || message.role === 'user');
|
||||||
|
const systemPromptMessages = messages.slice(0, firstChatMessage).filter(message => message.role === 'system' && !message.name);
|
||||||
|
|
||||||
|
if (systemPromptMessages.length) {
|
||||||
|
systemPromptText = systemPromptMessages.map(message => message.content).join('\n');
|
||||||
|
systemPromptText = formatInstructModeSystemPrompt(systemPromptText);
|
||||||
|
}
|
||||||
|
|
||||||
|
const exampleMessages = messages.filter(x => x.role === 'system' && (x.name === 'example_user' || x.name === 'example_assistant'));
|
||||||
|
|
||||||
|
if (exampleMessages.length) {
|
||||||
|
examplesText = power_user.context.example_separator + '\n';
|
||||||
|
examplesText += exampleMessages.map(toString).join('\n');
|
||||||
|
examplesText = formatInstructModeExamples(examplesText, name1, name2);
|
||||||
|
}
|
||||||
|
|
||||||
|
const chatMessages = messages.slice(firstChatMessage);
|
||||||
|
|
||||||
|
if (chatMessages.length) {
|
||||||
|
chatMessagesText = power_user.context.chat_start + '\n';
|
||||||
|
|
||||||
|
for (const message of chatMessages) {
|
||||||
|
const name = getPrefix(message);
|
||||||
|
const isUser = message.role === 'user';
|
||||||
|
const isNarrator = message.role === 'system';
|
||||||
|
chatMessagesText += formatInstructModeChat(name, message.content, isUser, isNarrator, '', name1, name2, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const isImpersonate = type === 'impersonate';
|
||||||
|
const promptName = isImpersonate ? name1 : name2;
|
||||||
|
const promptLine = formatInstructModePrompt(promptName, isImpersonate, '', name1, name2).trimStart();
|
||||||
|
|
||||||
|
const prompt = [systemPromptText, examplesText, chatMessagesText, promptLine]
|
||||||
|
.filter(x => x)
|
||||||
|
.map(x => x.endsWith('\n') ? x : `${x}\n`)
|
||||||
|
.join('');
|
||||||
|
|
||||||
|
return prompt;
|
||||||
|
}
|
||||||
|
|
||||||
function setOpenAIMessages(chat) {
|
function setOpenAIMessages(chat) {
|
||||||
let j = 0;
|
let j = 0;
|
||||||
// clean openai msgs
|
// clean openai msgs
|
||||||
|
@ -1222,11 +1309,16 @@ async function sendOpenAIRequest(type, openai_msgs_tosend, signal) {
|
||||||
const isScale = oai_settings.chat_completion_source == chat_completion_sources.SCALE;
|
const isScale = oai_settings.chat_completion_source == chat_completion_sources.SCALE;
|
||||||
const isAI21 = oai_settings.chat_completion_source == chat_completion_sources.AI21;
|
const isAI21 = oai_settings.chat_completion_source == chat_completion_sources.AI21;
|
||||||
const isPalm = oai_settings.chat_completion_source == chat_completion_sources.PALM;
|
const isPalm = oai_settings.chat_completion_source == chat_completion_sources.PALM;
|
||||||
const isTextCompletion = oai_settings.chat_completion_source == chat_completion_sources.OPENAI && textCompletionModels.includes(oai_settings.openai_model);
|
const isOAI = oai_settings.chat_completion_source == chat_completion_sources.OPENAI;
|
||||||
|
const isTextCompletion = (isOAI && textCompletionModels.includes(oai_settings.openai_model)) || (isOpenRouter && oai_settings.openrouter_force_instruct && power_user.instruct.enabled);
|
||||||
const isQuiet = type === 'quiet';
|
const isQuiet = type === 'quiet';
|
||||||
const isImpersonate = type === 'impersonate';
|
const isImpersonate = type === 'impersonate';
|
||||||
const stream = oai_settings.stream_openai && !isQuiet && !isScale && !isAI21 && !isPalm;
|
const stream = oai_settings.stream_openai && !isQuiet && !isScale && !isAI21 && !isPalm;
|
||||||
|
|
||||||
|
if (isTextCompletion && isOpenRouter) {
|
||||||
|
openai_msgs_tosend = convertChatCompletionToInstruct(openai_msgs_tosend, type);
|
||||||
|
}
|
||||||
|
|
||||||
if (isAI21 || isPalm) {
|
if (isAI21 || isPalm) {
|
||||||
const joinedMsgs = openai_msgs_tosend.reduce((acc, obj) => {
|
const joinedMsgs = openai_msgs_tosend.reduce((acc, obj) => {
|
||||||
const prefix = prefixMap[obj.role];
|
const prefix = prefixMap[obj.role];
|
||||||
|
@ -2034,6 +2126,7 @@ function loadOpenAISettings(data, settings) {
|
||||||
oai_settings.windowai_model = settings.windowai_model ?? default_settings.windowai_model;
|
oai_settings.windowai_model = settings.windowai_model ?? default_settings.windowai_model;
|
||||||
oai_settings.openrouter_model = settings.openrouter_model ?? default_settings.openrouter_model;
|
oai_settings.openrouter_model = settings.openrouter_model ?? default_settings.openrouter_model;
|
||||||
oai_settings.openrouter_use_fallback = settings.openrouter_use_fallback ?? default_settings.openrouter_use_fallback;
|
oai_settings.openrouter_use_fallback = settings.openrouter_use_fallback ?? default_settings.openrouter_use_fallback;
|
||||||
|
oai_settings.openrouter_force_instruct = settings.openrouter_force_instruct ?? default_settings.openrouter_force_instruct;
|
||||||
oai_settings.ai21_model = settings.ai21_model ?? default_settings.ai21_model;
|
oai_settings.ai21_model = settings.ai21_model ?? default_settings.ai21_model;
|
||||||
oai_settings.chat_completion_source = settings.chat_completion_source ?? default_settings.chat_completion_source;
|
oai_settings.chat_completion_source = settings.chat_completion_source ?? default_settings.chat_completion_source;
|
||||||
oai_settings.api_url_scale = settings.api_url_scale ?? default_settings.api_url_scale;
|
oai_settings.api_url_scale = settings.api_url_scale ?? default_settings.api_url_scale;
|
||||||
|
@ -2085,6 +2178,7 @@ function loadOpenAISettings(data, settings) {
|
||||||
$('#exclude_assistant').prop('checked', oai_settings.exclude_assistant);
|
$('#exclude_assistant').prop('checked', oai_settings.exclude_assistant);
|
||||||
$('#scale-alt').prop('checked', oai_settings.use_alt_scale);
|
$('#scale-alt').prop('checked', oai_settings.use_alt_scale);
|
||||||
$('#openrouter_use_fallback').prop('checked', oai_settings.openrouter_use_fallback);
|
$('#openrouter_use_fallback').prop('checked', oai_settings.openrouter_use_fallback);
|
||||||
|
$('#openrouter_force_instruct').prop('checked', oai_settings.openrouter_force_instruct);
|
||||||
$('#squash_system_messages').prop('checked', oai_settings.squash_system_messages);
|
$('#squash_system_messages').prop('checked', oai_settings.squash_system_messages);
|
||||||
if (settings.impersonation_prompt !== undefined) oai_settings.impersonation_prompt = settings.impersonation_prompt;
|
if (settings.impersonation_prompt !== undefined) oai_settings.impersonation_prompt = settings.impersonation_prompt;
|
||||||
|
|
||||||
|
@ -2251,6 +2345,7 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) {
|
||||||
windowai_model: settings.windowai_model,
|
windowai_model: settings.windowai_model,
|
||||||
openrouter_model: settings.openrouter_model,
|
openrouter_model: settings.openrouter_model,
|
||||||
openrouter_use_fallback: settings.openrouter_use_fallback,
|
openrouter_use_fallback: settings.openrouter_use_fallback,
|
||||||
|
openrouter_force_instruct: settings.openrouter_force_instruct,
|
||||||
ai21_model: settings.ai21_model,
|
ai21_model: settings.ai21_model,
|
||||||
temperature: settings.temp_openai,
|
temperature: settings.temp_openai,
|
||||||
frequency_penalty: settings.freq_pen_openai,
|
frequency_penalty: settings.freq_pen_openai,
|
||||||
|
@ -2612,6 +2707,7 @@ function onSettingsPresetChange() {
|
||||||
windowai_model: ['#model_windowai_select', 'windowai_model', false],
|
windowai_model: ['#model_windowai_select', 'windowai_model', false],
|
||||||
openrouter_model: ['#model_openrouter_select', 'openrouter_model', false],
|
openrouter_model: ['#model_openrouter_select', 'openrouter_model', false],
|
||||||
openrouter_use_fallback: ['#openrouter_use_fallback', 'openrouter_use_fallback', true],
|
openrouter_use_fallback: ['#openrouter_use_fallback', 'openrouter_use_fallback', true],
|
||||||
|
openrouter_force_instruct: ['#openrouter_force_instruct', 'openrouter_force_instruct', true],
|
||||||
ai21_model: ['#model_ai21_select', 'ai21_model', false],
|
ai21_model: ['#model_ai21_select', 'ai21_model', false],
|
||||||
openai_max_context: ['#openai_max_context', 'openai_max_context', false],
|
openai_max_context: ['#openai_max_context', 'openai_max_context', false],
|
||||||
openai_max_tokens: ['#openai_max_tokens', 'openai_max_tokens', false],
|
openai_max_tokens: ['#openai_max_tokens', 'openai_max_tokens', false],
|
||||||
|
@ -3344,6 +3440,11 @@ $(document).ready(async function () {
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#openrouter_force_instruct').on('input', function () {
|
||||||
|
oai_settings.openrouter_force_instruct = !!$(this).prop('checked');
|
||||||
|
saveSettingsDebounced();
|
||||||
|
});
|
||||||
|
|
||||||
$('#squash_system_messages').on('input', function () {
|
$('#squash_system_messages').on('input', function () {
|
||||||
oai_settings.squash_system_messages = !!$(this).prop('checked');
|
oai_settings.squash_system_messages = !!$(this).prop('checked');
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
|
|
|
@ -2849,6 +2849,10 @@ app.post("/openai_bias", jsonParser, async function (request, response) {
|
||||||
});
|
});
|
||||||
|
|
||||||
function convertChatMLPrompt(messages) {
|
function convertChatMLPrompt(messages) {
|
||||||
|
if (typeof messages === 'string') {
|
||||||
|
return messages;
|
||||||
|
}
|
||||||
|
|
||||||
const messageStrings = [];
|
const messageStrings = [];
|
||||||
messages.forEach(m => {
|
messages.forEach(m => {
|
||||||
if (m.role === 'system' && m.name === undefined) {
|
if (m.role === 'system' && m.name === undefined) {
|
||||||
|
@ -3180,9 +3184,9 @@ app.post("/generate_openai", jsonParser, function (request, response_generate_op
|
||||||
bodyParams['stop'] = request.body.stop;
|
bodyParams['stop'] = request.body.stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isTextCompletion = Boolean(request.body.model && TEXT_COMPLETION_MODELS.includes(request.body.model));
|
const isTextCompletion = Boolean(request.body.model && TEXT_COMPLETION_MODELS.includes(request.body.model)) || typeof request.body.messages === 'string';
|
||||||
const textPrompt = isTextCompletion ? convertChatMLPrompt(request.body.messages) : '';
|
const textPrompt = isTextCompletion ? convertChatMLPrompt(request.body.messages) : '';
|
||||||
const endpointUrl = isTextCompletion ? `${api_url}/completions` : `${api_url}/chat/completions`;
|
const endpointUrl = isTextCompletion && !request.body.use_openrouter ? `${api_url}/completions` : `${api_url}/chat/completions`;
|
||||||
|
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
request.socket.removeAllListeners('close');
|
request.socket.removeAllListeners('close');
|
||||||
|
|
Loading…
Reference in New Issue