Merge pull request #1810 from SillyTavern/staging

Staging
This commit is contained in:
Cohee 2024-02-10 21:24:42 +02:00 committed by GitHub
commit 91f31e746e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 140 additions and 1180 deletions

View File

@ -1,37 +0,0 @@
name: Build and Publish Release (Release)
on:
push:
branches:
- release
jobs:
build_and_publish:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: 18
- name: Install dependencies
run: npm ci
- name: Build and package with pkg
run: |
npm install -g pkg
npm run pkg
- name: Upload binaries to release
uses: softprops/action-gh-release@v1
with:
files: dist/*
tag_name: ci-release
name: Continuous Release (Release)
prerelease: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,37 +0,0 @@
name: Build and Publish Release (Staging)
on:
push:
branches:
- staging
jobs:
build_and_publish:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: 18
- name: Install dependencies
run: npm ci
- name: Build and package with pkg
run: |
npm install -g pkg
npm run pkg
- name: Upload binaries to release
uses: softprops/action-gh-release@v1
with:
files: dist/*
tag_name: ci-staging
name: Continuous Release (Staging)
prerelease: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

1008
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -55,11 +55,10 @@
"type": "git", "type": "git",
"url": "https://github.com/SillyTavern/SillyTavern.git" "url": "https://github.com/SillyTavern/SillyTavern.git"
}, },
"version": "1.11.3", "version": "1.11.4",
"scripts": { "scripts": {
"start": "node server.js", "start": "node server.js",
"start-multi": "node server.js --disableCsrf", "start-multi": "node server.js --disableCsrf",
"pkg": "pkg --compress Gzip --no-bytecode --public .",
"postinstall": "node post-install.js", "postinstall": "node post-install.js",
"lint": "eslint \"src/**/*.js\" \"public/**/*.js\" ./*.js", "lint": "eslint \"src/**/*.js\" \"public/**/*.js\" ./*.js",
"lint-fix": "eslint \"src/**/*.js\" \"public/**/*.js\" ./*.js --fix" "lint-fix": "eslint \"src/**/*.js\" \"public/**/*.js\" ./*.js --fix"
@ -72,24 +71,8 @@
"no-var": "off" "no-var": "off"
}, },
"main": "server.js", "main": "server.js",
"pkg": {
"targets": [
"node18-linux-x64",
"node18-macos-x64",
"node18-windows-x64"
],
"assets": [
"node_modules/**/*"
],
"outputPath": "dist",
"scripts": [
"server.js"
]
},
"devDependencies": { "devDependencies": {
"eslint": "^8.55.0", "eslint": "^8.55.0",
"jquery": "^3.6.4", "jquery": "^3.6.4"
"pkg": "^5.8.1",
"pkg-fetch": "^3.5.2"
} }
} }

View File

@ -1277,7 +1277,7 @@
<div data-newbie-hidden data-tg-type="ooba, koboldcpp, aphrodite, tabby" class="alignitemscenter flex-container flexFlowColumn flexBasis48p flexGrow flexShrink gap0"> <div data-newbie-hidden data-tg-type="ooba, koboldcpp, aphrodite, tabby" class="alignitemscenter flex-container flexFlowColumn flexBasis48p flexGrow flexShrink gap0">
<small data-i18n="Smoothing Factor">Smoothing Factor</small> <small data-i18n="Smoothing Factor">Smoothing Factor</small>
<input class="neo-range-slider" type="range" id="smoothing_factor_textgenerationwebui" name="volume" min="0" max="10" step="0.01" /> <input class="neo-range-slider" type="range" id="smoothing_factor_textgenerationwebui" name="volume" min="0" max="10" step="0.01" />
<input class="neo-range-input" type="number" min="0" max="5" step="0.01" data-for="smoothing_factor_textgenerationwebui" id="smoothing_factor_counter_textgenerationwebui"> <input class="neo-range-input" type="number" min="0" max="10" step="0.01" data-for="smoothing_factor_textgenerationwebui" id="smoothing_factor_counter_textgenerationwebui">
</div> </div>
<!-- <!--
<div data-tg-type="aphrodite" class="alignitemscenter flex-container flexFlowColumn flexBasis48p flexGrow flexShrink gap0" data-i18n="Responses"> <div data-tg-type="aphrodite" class="alignitemscenter flex-container flexFlowColumn flexBasis48p flexGrow flexShrink gap0" data-i18n="Responses">
@ -1916,6 +1916,15 @@
Make sure you run it with <code>--api</code> flag Make sure you run it with <code>--api</code> flag
</span> </span>
</div> </div>
<h4 data-i18n="API key (optional)">API key (optional)</h4>
<div class="flex-container">
<input id="api_key_ooba" name="api_key_ooba" 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_ooba">
</div>
</div>
<div data-for="api_key_ooba" 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"> <div class="flex1">
<h4 data-i18n="Server url">Server URL</h4> <h4 data-i18n="Server url">Server URL</h4>
<small data-i18n="Example: http://127.0.0.1:5000 ">Example: http://127.0.0.1:5000</small> <small data-i18n="Example: http://127.0.0.1:5000 ">Example: http://127.0.0.1:5000</small>

View File

@ -2179,6 +2179,7 @@ function substituteParams(content, _name1, _name2, _original, _group, _replaceCh
environment.user = _name1 ?? name1; environment.user = _name1 ?? name1;
environment.char = _name2 ?? name2; environment.char = _name2 ?? name2;
environment.group = environment.charIfNotGroup = _group ?? name2; environment.group = environment.charIfNotGroup = _group ?? name2;
environment.model = getGeneratingModel();
return evaluateMacros(content, environment); return evaluateMacros(content, environment);
} }
@ -6089,6 +6090,21 @@ export async function getPastCharacterChats(characterId = null) {
return data; return data;
} }
/**
* Helper for `displayPastChats`, to make the same info consistently available for other functions
*/
function getCurrentChatDetails() {
if (!characters[this_chid] && !selected_group) {
return { sessionName: '', group: null, characterName: '', avatarImgURL: '' };
}
const group = selected_group ? groups.find(x => x.id === selected_group) : null;
const currentChat = selected_group ? group?.chat_id : characters[this_chid]['chat'];
const displayName = selected_group ? group?.name : characters[this_chid].name;
const avatarImg = selected_group ? group?.avatar_url : getThumbnailUrl('avatar', characters[this_chid]['avatar']);
return { sessionName: currentChat, group: group, characterName: displayName, avatarImgURL: avatarImg };
}
/** /**
* Displays the past chats for a character or a group based on the selected context. * Displays the past chats for a character or a group based on the selected context.
* The function first fetches the chats, processes them, and then displays them in * The function first fetches the chats, processes them, and then displays them in
@ -6099,7 +6115,6 @@ export async function displayPastChats() {
$('#select_chat_div').empty(); $('#select_chat_div').empty();
$('#select_chat_search').val('').off('input'); $('#select_chat_search').val('').off('input');
const group = selected_group ? groups.find(x => x.id === selected_group) : null;
const data = await (selected_group ? getGroupPastChats(selected_group) : getPastCharacterChats()); const data = await (selected_group ? getGroupPastChats(selected_group) : getPastCharacterChats());
if (!data) { if (!data) {
@ -6107,10 +6122,14 @@ export async function displayPastChats() {
return; return;
} }
const currentChat = selected_group ? group?.chat_id : characters[this_chid]['chat']; const chatDetails = getCurrentChatDetails();
const displayName = selected_group ? group?.name : characters[this_chid].name; const group = chatDetails.group;
const avatarImg = selected_group ? group?.avatar_url : getThumbnailUrl('avatar', characters[this_chid]['avatar']); const currentChat = chatDetails.sessionName;
const displayName = chatDetails.characterName;
const avatarImg = chatDetails.avatarImgURL;
const rawChats = await getChatsFromFiles(data, selected_group); const rawChats = await getChatsFromFiles(data, selected_group);
// Sort by last message date descending // Sort by last message date descending
data.sort((a, b) => sortMoments(timestampToMoment(a.last_mes), timestampToMoment(b.last_mes))); data.sort((a, b) => sortMoments(timestampToMoment(a.last_mes), timestampToMoment(b.last_mes)));
console.log(data); console.log(data);
@ -7817,15 +7836,18 @@ async function doImpersonate() {
} }
async function doDeleteChat() { async function doDeleteChat() {
$('#option_select_chat').trigger('click', { fromSlashCommand: true }); await displayPastChats();
await delay(100);
let currentChatDeleteButton = $('.select_chat_block[highlight=\'true\']').parent().find('.PastChat_cross'); let currentChatDeleteButton = $('.select_chat_block[highlight=\'true\']').parent().find('.PastChat_cross');
$(currentChatDeleteButton).trigger('click', { fromSlashCommand: true }); $(currentChatDeleteButton).trigger('click');
await delay(1); await delay(1);
$('#dialogue_popup_ok').trigger('click'); $('#dialogue_popup_ok').trigger('click', { fromSlashCommand: true });
//200 delay needed let the past chat view reshow first }
await delay(200);
$('#select_chat_cross').trigger('click'); /**
* /getchatname` slash command
*/
async function doGetChatName() {
return getCurrentChatDetails().sessionName;
} }
const isPwaMode = window.navigator.standalone; const isPwaMode = window.navigator.standalone;
@ -7979,6 +8001,7 @@ jQuery(async function () {
registerSlashCommand('api', connectAPISlash, [], `<span class="monospace">(${Object.keys(CONNECT_API_MAP).join(', ')})</span> connect to an API`, true, true); registerSlashCommand('api', connectAPISlash, [], `<span class="monospace">(${Object.keys(CONNECT_API_MAP).join(', ')})</span> connect to an API`, true, true);
registerSlashCommand('impersonate', doImpersonate, ['imp'], ' calls an impersonation response', true, true); registerSlashCommand('impersonate', doImpersonate, ['imp'], ' calls an impersonation response', true, true);
registerSlashCommand('delchat', doDeleteChat, [], ' deletes the current chat', true, true); registerSlashCommand('delchat', doDeleteChat, [], ' deletes the current chat', true, true);
registerSlashCommand('getchatname', doGetChatName, [], ' returns the name of the current chat file into the pipe', false, true);
registerSlashCommand('closechat', doCloseChat, [], ' closes the current chat', true, true); registerSlashCommand('closechat', doCloseChat, [], ' closes the current chat', true, true);
registerSlashCommand('panels', doTogglePanels, ['togglepanels'], ' toggle UI panels on/off', true, true); registerSlashCommand('panels', doTogglePanels, ['togglepanels'], ' toggle UI panels on/off', true, true);
registerSlashCommand('forcesave', doForceSave, [], ' forces a save of the current chat and settings', true, true); registerSlashCommand('forcesave', doForceSave, [], ' forces a save of the current chat and settings', true, true);
@ -8208,7 +8231,8 @@ jQuery(async function () {
$('#character_popup').css('display', 'none'); $('#character_popup').css('display', 'none');
}); });
$('#dialogue_popup_ok').click(async function (e) { $('#dialogue_popup_ok').click(async function (e, customData) {
const fromSlashCommand = customData?.fromSlashCommand || false;
dialogueCloseStop = false; dialogueCloseStop = false;
$('#shadow_popup').transition({ $('#shadow_popup').transition({
opacity: 0, opacity: 0,
@ -8238,14 +8262,16 @@ jQuery(async function () {
await delChat(chat_file_for_del); await delChat(chat_file_for_del);
} }
//open the history view again after 2seconds (delay to avoid edge cases for deleting last chat) if (fromSlashCommand) { // When called from `/delchat` command, don't re-open the history view.
//hide option popup menu $('#options').hide(); // hide option popup menu
hideLoader();
} else { // Open the history view again after 2 seconds (delay to avoid edge cases for deleting last chat).
setTimeout(function () { setTimeout(function () {
$('#option_select_chat').click(); $('#option_select_chat').click();
$('#options').hide(); $('#options').hide(); // hide option popup menu
hideLoader(); hideLoader();
}, 2000); }, 2000);
}
} }
if (popup_type == 'del_ch') { if (popup_type == 'del_ch') {
const deleteChats = !!$('#del_char_checkbox').prop('checked'); const deleteChats = !!$('#del_char_checkbox').prop('checked');
@ -8541,6 +8567,11 @@ jQuery(async function () {
await writeSecret(SECRET_KEYS.TOGETHERAI, togetherKey); await writeSecret(SECRET_KEYS.TOGETHERAI, togetherKey);
} }
const oobaKey = String($('#api_key_ooba').val()).trim();
if (oobaKey.length) {
await writeSecret(SECRET_KEYS.OOBA, oobaKey);
}
validateTextGenUrl(); validateTextGenUrl();
startStatusLoading(); startStatusLoading();
main_api = 'textgenerationwebui'; main_api = 'textgenerationwebui';

View File

@ -1132,7 +1132,7 @@ export function initRossMods() {
.not('#right-nav-panel') .not('#right-nav-panel')
.not('#floatingPrompt') .not('#floatingPrompt')
.not('#cfgConfig') .not('#cfgConfig')
.not("#logprobsViewer") .not('#logprobsViewer')
.is(':visible')) { .is(':visible')) {
let visibleDrawerContent = $('.drawer-content:visible') let visibleDrawerContent = $('.drawer-content:visible')
.not('#WorldInfo') .not('#WorldInfo')
@ -1140,7 +1140,7 @@ export function initRossMods() {
.not('#right-nav-panel') .not('#right-nav-panel')
.not('#floatingPrompt') .not('#floatingPrompt')
.not('#cfgConfig') .not('#cfgConfig')
.not("#logprobsViewer"); .not('#logprobsViewer');
$(visibleDrawerContent).parent().find('.drawer-icon').trigger('click'); $(visibleDrawerContent).parent().find('.drawer-icon').trigger('click');
return; return;
} }

View File

@ -1688,7 +1688,7 @@ async function fetchImagesNoCache() {
// Pause Talkinghead to save resources when the ST tab is not visible or the window is minimized. // Pause Talkinghead to save resources when the ST tab is not visible or the window is minimized.
// We currently do this via loading/unloading. Could be improved by adding new pause/unpause endpoints to Extras. // We currently do this via loading/unloading. Could be improved by adding new pause/unpause endpoints to Extras.
document.addEventListener("visibilitychange", function (event) { document.addEventListener('visibilitychange', function (event) {
let pageIsVisible; let pageIsVisible;
if (document.hidden) { if (document.hidden) {
console.debug('expressions: SillyTavern is now hidden'); console.debug('expressions: SillyTavern is now hidden');

View File

@ -536,7 +536,7 @@ async function processTtsQueue() {
} }
if (extension_settings.tts.narrate_quoted_only) { if (extension_settings.tts.narrate_quoted_only) {
const special_quotes = /[“”]/g; // Extend this regex to include other special quotes const special_quotes = /[“”«»]/g; // Extend this regex to include other special quotes
text = text.replace(special_quotes, '"'); text = text.replace(special_quotes, '"');
const matches = text.match(/".*?"/g); // Matches text inside double quotes, non-greedily const matches = text.match(/".*?"/g); // Matches text inside double quotes, non-greedily
const partJoiner = (ttsProvider?.separator || ' ... '); const partJoiner = (ttsProvider?.separator || ' ... ');

View File

@ -674,7 +674,7 @@ export function parseNovelAILogprobs(data) {
// them with a logprob of -Infinity (0% probability) // them with a logprob of -Infinity (0% probability)
const notInAfter = befores const notInAfter = befores
.filter(([id]) => !afters.some(([aid]) => aid === id)) .filter(([id]) => !afters.some(([aid]) => aid === id))
.map(([id]) => [id, -Infinity]) .map(([id]) => [id, -Infinity]);
const merged = afters.concat(notInAfter); const merged = afters.concat(notInAfter);
// Add the chosen token to `merged` if it's not already there. This can // Add the chosen token to `merged` if it's not already there. This can

View File

@ -31,6 +31,7 @@ import {
this_chid, this_chid,
} from '../script.js'; } from '../script.js';
import { groups, selected_group } from './group-chats.js'; import { groups, selected_group } from './group-chats.js';
import { registerSlashCommand } from './slash-commands.js';
import { import {
chatCompletionDefaultPrompts, chatCompletionDefaultPrompts,
@ -1691,24 +1692,17 @@ async function sendOpenAIRequest(type, messages, signal) {
throw new Error(`Got response status ${response.status}`); throw new Error(`Got response status ${response.status}`);
} }
if (stream) { if (stream) {
let reader;
let isSSEStream = oai_settings.chat_completion_source !== chat_completion_sources.MAKERSUITE;
if (isSSEStream) {
const eventStream = new EventSourceStream(); const eventStream = new EventSourceStream();
response.body.pipeThrough(eventStream); response.body.pipeThrough(eventStream);
reader = eventStream.readable.getReader(); const reader = eventStream.readable.getReader();
} else {
reader = response.body.getReader();
}
return async function* streamData() { return async function* streamData() {
let text = ''; let text = '';
let utf8Decoder = new TextDecoder();
const swipes = []; const swipes = [];
while (true) { while (true) {
const { done, value } = await reader.read(); const { done, value } = await reader.read();
if (done) return; if (done) return;
const rawData = isSSEStream ? value.data : utf8Decoder.decode(value, { stream: true }); const rawData = value.data;
if (isSSEStream && rawData === '[DONE]') return; if (rawData === '[DONE]') return;
tryParseStreamingError(response, rawData); tryParseStreamingError(response, rawData);
const parsed = JSON.parse(rawData); const parsed = JSON.parse(rawData);
@ -1749,7 +1743,7 @@ function getStreamingReply(data) {
if (oai_settings.chat_completion_source == chat_completion_sources.CLAUDE) { if (oai_settings.chat_completion_source == chat_completion_sources.CLAUDE) {
return data?.completion || ''; return data?.completion || '';
} else if (oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE) { } else if (oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE) {
return data?.candidates[0].content.parts[0].text || ''; return data?.candidates?.[0]?.content?.parts?.[0]?.text || '';
} else { } else {
return data.choices[0]?.delta?.content || data.choices[0]?.message?.content || data.choices[0]?.text || ''; return data.choices[0]?.delta?.content || data.choices[0]?.message?.content || data.choices[0]?.text || '';
} }
@ -3934,6 +3928,28 @@ $('#delete_proxy').on('click', async function () {
} }
}); });
function runProxyCallback(_, value) {
if (!value) {
toastr.warning('Proxy preset name is required');
return '';
}
const proxyNames = proxies.map(preset => preset.name);
const fuse = new Fuse(proxyNames);
const result = fuse.search(value);
if (result.length === 0) {
toastr.warning(`Proxy preset "${value}" not found`);
return '';
}
const foundName = result[0].item;
$('#openai_proxy_preset').val(foundName).trigger('change');
return foundName;
}
registerSlashCommand('proxy', runProxyCallback, [], '<span class="monospace">(name)</span> sets a proxy preset by name');
$(document).ready(async function () { $(document).ready(async function () {
$('#test_api_button').on('click', testApiConnection); $('#test_api_button').on('click', testApiConnection);

View File

@ -17,6 +17,7 @@ export const SECRET_KEYS = {
MISTRALAI: 'api_key_mistralai', MISTRALAI: 'api_key_mistralai',
TOGETHERAI: 'api_key_togetherai', TOGETHERAI: 'api_key_togetherai',
CUSTOM: 'api_key_custom', CUSTOM: 'api_key_custom',
OOBA: 'api_key_ooba',
}; };
const INPUT_MAP = { const INPUT_MAP = {
@ -35,6 +36,7 @@ const INPUT_MAP = {
[SECRET_KEYS.MISTRALAI]: '#api_key_mistralai', [SECRET_KEYS.MISTRALAI]: '#api_key_mistralai',
[SECRET_KEYS.CUSTOM]: '#api_key_custom', [SECRET_KEYS.CUSTOM]: '#api_key_custom',
[SECRET_KEYS.TOGETHERAI]: '#api_key_togetherai', [SECRET_KEYS.TOGETHERAI]: '#api_key_togetherai',
[SECRET_KEYS.OOBA]: '#api_key_ooba',
}; };
async function clearSecret() { async function clearSecret() {

View File

@ -154,7 +154,7 @@ parser.addCommand('sysgen', generateSystemMessage, [], '<span class="monospace">
parser.addCommand('ask', askCharacter, [], '<span class="monospace">(prompt)</span> asks a specified character card a prompt', true, true); parser.addCommand('ask', askCharacter, [], '<span class="monospace">(prompt)</span> asks a specified character card a prompt', true, true);
parser.addCommand('delname', deleteMessagesByNameCallback, ['cancel'], '<span class="monospace">(name)</span> deletes all messages attributed to a specified name', true, true); parser.addCommand('delname', deleteMessagesByNameCallback, ['cancel'], '<span class="monospace">(name)</span> deletes all messages attributed to a specified name', true, true);
parser.addCommand('send', sendUserMessageCallback, [], '<span class="monospace">(text)</span> adds a user message to the chat log without triggering a generation', true, true); parser.addCommand('send', sendUserMessageCallback, [], '<span class="monospace">(text)</span> adds a user message to the chat log without triggering a generation', true, true);
parser.addCommand('trigger', triggerGenerationCallback, [], ' triggers a message generation. If in group, can trigger a message for the specified group member index or name.', true, true); parser.addCommand('trigger', triggerGenerationCallback, [], ' <span class="monospace">await=true/false</span> triggers a message generation. If in group, can trigger a message for the specified group member index or name. If <code>await=true</code> named argument passed, the command will await for the triggered generation before continuing.', true, true);
parser.addCommand('hide', hideMessageCallback, [], '<span class="monospace">(message index or range)</span> hides a chat message from the prompt', true, true); parser.addCommand('hide', hideMessageCallback, [], '<span class="monospace">(message index or range)</span> hides a chat message from the prompt', true, true);
parser.addCommand('unhide', unhideMessageCallback, [], '<span class="monospace">(message index or range)</span> unhides a message from the prompt', true, true); parser.addCommand('unhide', unhideMessageCallback, [], '<span class="monospace">(message index or range)</span> unhides a message from the prompt', true, true);
parser.addCommand('disable', disableGroupMemberCallback, [], '<span class="monospace">(member index or name)</span> disables a group member from being drafted for replies', true, true); parser.addCommand('disable', disableGroupMemberCallback, [], '<span class="monospace">(member index or name)</span> disables a group member from being drafted for replies', true, true);
@ -1029,8 +1029,9 @@ async function addGroupMemberCallback(_, arg) {
return character.name; return character.name;
} }
async function triggerGenerationCallback(_, arg) { async function triggerGenerationCallback(args, value) {
setTimeout(async () => { const shouldAwait = isTrueBoolean(args?.await);
const outerPromise = new Promise((outerResolve) => setTimeout(async () => {
try { try {
await waitUntilCondition(() => !is_send_press && !is_group_generating, 10000, 100); await waitUntilCondition(() => !is_send_press && !is_group_generating, 10000, 100);
} catch { } catch {
@ -1044,16 +1045,21 @@ async function triggerGenerationCallback(_, arg) {
let chid = undefined; let chid = undefined;
if (selected_group && arg) { if (selected_group && value) {
chid = findGroupMemberId(arg); chid = findGroupMemberId(value);
if (chid === undefined) { if (chid === undefined) {
console.warn(`WARN: No group member found for argument ${arg}`); console.warn(`WARN: No group member found for argument ${value}`);
} }
} }
setTimeout(() => Generate('normal', { force_chid: chid }), 100); outerResolve(new Promise(innerResolve => setTimeout(() => innerResolve(Generate('normal', { force_chid: chid })), 100)));
}, 1); }, 1));
if (shouldAwait) {
const innerPromise = await outerPromise;
await innerPromise;
}
return ''; return '';
} }

View File

@ -716,6 +716,7 @@ function parseTextgenLogprobs(token, logprobs) {
} }
switch (settings.type) { switch (settings.type) {
case TABBY:
case APHRODITE: case APHRODITE:
case OOBA: { case OOBA: {
/** @type {Record<string, number>[]} */ /** @type {Record<string, number>[]} */
@ -807,6 +808,8 @@ export function getTextGenGenerationData(finalPrompt, maxTokens, isImpersonate,
'temperature': settings.dynatemp ? (settings.min_temp + settings.max_temp) / 2 : settings.temp, 'temperature': settings.dynatemp ? (settings.min_temp + settings.max_temp) / 2 : settings.temp,
'top_p': settings.top_p, 'top_p': settings.top_p,
'typical_p': settings.typical_p, 'typical_p': settings.typical_p,
'typical': settings.typical_p,
'sampler_seed': settings.seed,
'min_p': settings.min_p, 'min_p': settings.min_p,
'repetition_penalty': settings.rep_pen, 'repetition_penalty': settings.rep_pen,
'frequency_penalty': settings.freq_pen, 'frequency_penalty': settings.freq_pen,
@ -819,8 +822,8 @@ export function getTextGenGenerationData(finalPrompt, maxTokens, isImpersonate,
'early_stopping': settings.early_stopping, 'early_stopping': settings.early_stopping,
'add_bos_token': settings.add_bos_token, 'add_bos_token': settings.add_bos_token,
'dynamic_temperature': settings.dynatemp, 'dynamic_temperature': settings.dynatemp,
'dynatemp_low': settings.dynatemp ? settings.min_temp : 0, 'dynatemp_low': settings.dynatemp ? settings.min_temp : 1,
'dynatemp_high': settings.dynatemp ? settings.max_temp : 0, 'dynatemp_high': settings.dynatemp ? settings.max_temp : 1,
'dynatemp_range': settings.dynatemp ? (settings.max_temp - settings.min_temp) / 2 : 0, 'dynatemp_range': settings.dynatemp ? (settings.max_temp - settings.min_temp) / 2 : 0,
'dynatemp_exponent': settings.dynatemp ? settings.dynatemp_exponent : 1, 'dynatemp_exponent': settings.dynatemp ? settings.dynatemp_exponent : 1,
'smoothing_factor': settings.smoothing_factor, 'smoothing_factor': settings.smoothing_factor,

0
public/user/.gitkeep Normal file
View File

View File

@ -37,6 +37,14 @@ function getTabbyHeaders() {
}) : {}; }) : {};
} }
function getOobaHeaders() {
const apiKey = readSecret(SECRET_KEYS.OOBA);
return apiKey ? ({
'Authorization': `Bearer ${apiKey}`,
}) : {};
}
function getOverrideHeaders(urlHost) { function getOverrideHeaders(urlHost) {
const requestOverrides = getConfigValue('requestOverrides', []); const requestOverrides = getConfigValue('requestOverrides', []);
const overrideHeaders = requestOverrides?.find((e) => e.hosts?.includes(urlHost))?.headers; const overrideHeaders = requestOverrides?.find((e) => e.hosts?.includes(urlHost))?.headers;
@ -69,6 +77,9 @@ function setAdditionalHeaders(request, args, server) {
case TEXTGEN_TYPES.TOGETHERAI: case TEXTGEN_TYPES.TOGETHERAI:
headers = getTogetherAIHeaders(); headers = getTogetherAIHeaders();
break; break;
case TEXTGEN_TYPES.OOBA:
headers = getOobaHeaders();
break;
default: default:
headers = server ? getOverrideHeaders((new URL(server))?.host) : {}; headers = server ? getOverrideHeaders((new URL(server))?.host) : {};
break; break;

View File

@ -1,5 +1,6 @@
const DIRECTORIES = { const DIRECTORIES = {
worlds: 'public/worlds/', worlds: 'public/worlds/',
user: 'public/user',
avatars: 'public/User Avatars', avatars: 'public/User Avatars',
images: 'public/img/', images: 'public/img/',
userImages: 'public/user/images/', userImages: 'public/user/images/',

View File

@ -267,7 +267,7 @@ async function sendMakerSuiteRequest(request, response) {
? (stream ? 'streamGenerateContent' : 'generateContent') ? (stream ? 'streamGenerateContent' : 'generateContent')
: (isText ? 'generateText' : 'generateMessage'); : (isText ? 'generateText' : 'generateMessage');
const generateResponse = await fetch(`https://generativelanguage.googleapis.com/${apiVersion}/models/${model}:${responseType}?key=${apiKey}`, { const generateResponse = await fetch(`https://generativelanguage.googleapis.com/${apiVersion}/models/${model}:${responseType}?key=${apiKey}${stream ? '&alt=sse' : ''}`, {
body: JSON.stringify(body), body: JSON.stringify(body),
method: 'POST', method: 'POST',
headers: { headers: {
@ -279,36 +279,8 @@ async function sendMakerSuiteRequest(request, response) {
// have to do this because of their busted ass streaming endpoint // have to do this because of their busted ass streaming endpoint
if (stream) { if (stream) {
try { try {
let partialData = ''; // Pipe remote SSE stream to Express response
generateResponse.body.on('data', (data) => { forwardFetchResponse(generateResponse, response);
const chunk = data.toString();
if (chunk.startsWith(',') || chunk.endsWith(',') || chunk.startsWith('[') || chunk.endsWith(']')) {
partialData = chunk.slice(1);
} else {
partialData += chunk;
}
while (true) {
let json;
try {
json = JSON.parse(partialData);
} catch (e) {
break;
}
response.write(JSON.stringify(json));
partialData = '';
}
});
request.socket.on('close', function () {
if (generateResponse.body instanceof Readable) generateResponse.body.destroy();
response.end();
});
generateResponse.body.on('end', () => {
console.log('Streaming request finished');
response.end();
});
} catch (error) { } catch (error) {
console.log('Error forwarding streaming response:', error); console.log('Error forwarding streaming response:', error);
if (!response.headersSent) { if (!response.headersSent) {
@ -719,7 +691,7 @@ router.post('/generate', jsonParser, function (request, response) {
// Adjust logprobs params for Chat Completions API, which expects { top_logprobs: number; logprobs: boolean; } // Adjust logprobs params for Chat Completions API, which expects { top_logprobs: number; logprobs: boolean; }
if (!isTextCompletion && bodyParams.logprobs > 0) { if (!isTextCompletion && bodyParams.logprobs > 0) {
bodyParams.top_logprobs = bodyParams.logprobs; bodyParams.top_logprobs = bodyParams.logprobs;
bodyParams.logprobs = true bodyParams.logprobs = true;
} }
if (getConfigValue('openai.randomizeUserId', false)) { if (getConfigValue('openai.randomizeUserId', false)) {

View File

@ -216,7 +216,7 @@ router.post('/generate', jsonParser, async function (req, res) {
} }
const data = await response.json(); const data = await response.json();
console.log("NovelAI Output", data?.output); console.log('NovelAI Output', data?.output);
return res.send(data); return res.send(data);
} }
} catch (error) { } catch (error) {

View File

@ -33,6 +33,7 @@ router.post('/caption-image', jsonParser, async (request, response) => {
} }
if (request.body.api === 'ooba') { if (request.body.api === 'ooba') {
key = readSecret(SECRET_KEYS.OOBA);
bodyParams.temperature = 0.1; bodyParams.temperature = 0.1;
} }

View File

@ -29,6 +29,7 @@ const SECRET_KEYS = {
TOGETHERAI: 'api_key_togetherai', TOGETHERAI: 'api_key_togetherai',
MISTRALAI: 'api_key_mistralai', MISTRALAI: 'api_key_mistralai',
CUSTOM: 'api_key_custom', CUSTOM: 'api_key_custom',
OOBA: 'api_key_ooba',
}; };
/** /**

View File

@ -172,7 +172,7 @@ function getSourceSettings(source, request) {
const sourceSettings = { const sourceSettings = {
extrasUrl: extrasUrl, extrasUrl: extrasUrl,
extrasKey: extrasKey extrasKey: extrasKey,
}; };
return sourceSettings; return sourceSettings;
} }