#1059 Mancer model selector

This commit is contained in:
Cohee 2023-09-10 04:08:15 +03:00
parent 3dbdd1258e
commit 0480acebcd
6 changed files with 162 additions and 14 deletions

View File

@ -19,11 +19,24 @@
color: var(--SmartThemeBodyColor); color: var(--SmartThemeBodyColor);
} }
.select2-container .select2-search__field {
opacity: 0.8;
}
.select2-container .select2-selection--single .select2-selection__rendered {
color: var(--SmartThemeBodyColor);
line-height: revert;
padding-left: unset;
}
.select2-container .select2-results>.select2-results__options {
max-height: 300px;
}
.select2-container .select2-selection--multiple .select2-selection__choice__remove { .select2-container .select2-selection--multiple .select2-selection__choice__remove {
padding: revert; padding: revert;
border-right: 1px solid var(--white30a); border-right: 1px solid var(--white30a);
font-size: 1.1em; font-size: 1.1em;
} }
.select2-container .select2-selection--multiple .select2-selection__choice__display { .select2-container .select2-selection--multiple .select2-selection__choice__display {
@ -58,7 +71,8 @@
background-color: var(--SmartThemeBodyColor); background-color: var(--SmartThemeBodyColor);
} }
.select2-container .select2-selection--multiple { .select2-container .select2-selection--multiple,
.select2-container .select2-selection--single {
background-color: var(--black30a); background-color: var(--black30a);
color: var(--SmartThemeBodyColor); color: var(--SmartThemeBodyColor);
border: 1px solid var(--white30a); border: 1px solid var(--white30a);
@ -67,11 +81,13 @@
padding: 3px 5px; padding: 3px 5px;
} }
.select2-container.select2-container--focus .select2-selection--multiple { .select2-container.select2-container--focus .select2-selection--multiple,
.select2-container.select2-container--focus .select2-selection--single {
border: 1px solid var(--white30a); border: 1px solid var(--white30a);
} }
.select2-container .select2-selection--multiple .select2-selection__choice { .select2-container .select2-selection--multiple .select2-selection__choice,
.select2-container .select2-selection--single .select2-selection__choice {
border-radius: 5px; border-radius: 5px;
border-style: solid; border-style: solid;
border-width: 1px; border-width: 1px;
@ -119,7 +135,8 @@
border-radius: 2px; border-radius: 2px;
} }
.select2-container .select2-selection--multiple .select2-selection__choice__remove { .select2-container .select2-selection--multiple .select2-selection__choice__remove,
.select2-container .select2-selection--single .select2-selection__choice__remove {
color: var(--SmartThemeBodyColor); color: var(--SmartThemeBodyColor);
} }

View File

@ -39,6 +39,7 @@
<script src="lib/toastr.min.js"></script> <script src="lib/toastr.min.js"></script>
<script src="lib/fuse.js"></script> <script src="lib/fuse.js"></script>
<script src="lib/select2.min.js"></script> <script src="lib/select2.min.js"></script>
<script src="lib/select2-search-placeholder.js"></script>
<script src="lib/seedrandom.min.js"></script> <script src="lib/seedrandom.min.js"></script>
<script src="lib/droll.js"></script> <script src="lib/droll.js"></script>
<script src="lib/localforage.min.js"></script> <script src="lib/localforage.min.js"></script>
@ -72,6 +73,7 @@
<script type="module" src="scripts/group-chats.js"></script> <script type="module" src="scripts/group-chats.js"></script>
<script type="module" src="scripts/kai-settings.js"></script> <script type="module" src="scripts/kai-settings.js"></script>
<script type="module" src="scripts/textgen-settings.js"></script> <script type="module" src="scripts/textgen-settings.js"></script>
<script type="module" src="scripts/mancer-settings.js"></script>
<script type="module" src="scripts/bookmarks.js"></script> <script type="module" src="scripts/bookmarks.js"></script>
<script type="module" src="scripts/horde.js"></script> <script type="module" src="scripts/horde.js"></script>
<script type="module" src="scripts/RossAscends-mods.js"></script> <script type="module" src="scripts/RossAscends-mods.js"></script>
@ -1849,19 +1851,21 @@
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>
<div class="flex1"> <div class="flex1">
<h4 data-i18n="Mancer API url">Mancer API url</h4> <h4>Mancer Model</h4>
<small data-i18n="Example: https://neuro.mancer.tech/webui/MODEL/api">Example: https://neuro.mancer.tech/webui/MODEL/api </small> <select id="mancer_model"></select>
<h4 data-i18n="Mancer API url">Mancer API URL</h4>
<small data-i18n="Example: https://neuro.mancer.tech/webui/MODEL/api">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"> <input id="mancer_api_url_text" name="mancer_api_url" class="text_pole wide100p" maxlength="500" value="" autocomplete="off">
</div> </div>
</div> </div>
<div id="tgwebui_api_subpanel" class="flex-container flexFlowColumn"> <div id="tgwebui_api_subpanel" class="flex-container flexFlowColumn">
<div class="flex1"> <div class="flex1">
<h4 data-i18n="Blocking API url">Blocking API url</h4> <h4 data-i18n="Blocking API url">Blocking API URL</h4>
<small data-i18n="Example: http://127.0.0.1:5000/api ">Example: http://127.0.0.1:5000/api </small> <small data-i18n="Example: http://127.0.0.1:5000/api ">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" data-server-history="ooba_blocking"> <input id="textgenerationwebui_api_url_text" name="textgenerationwebui_api_url" class="text_pole wide100p" maxlength="500" value="" autocomplete="off" data-server-history="ooba_blocking">
</div> </div>
<div class="flex1"> <div class="flex1">
<h4 data-i18n="Streaming API url">Streaming API url</h4> <h4 data-i18n="Streaming API url">Streaming API URL</h4>
<small data-i18n="Example: ws://127.0.0.1:5005/api/v1/stream">Example: ws://127.0.0.1:5005/api/v1/stream </small> <small data-i18n="Example: ws://127.0.0.1:5005/api/v1/stream">Example: ws://127.0.0.1:5005/api/v1/stream </small>
<input id="streaming_url_textgenerationwebui" type="text" class="text_pole wide100p" maxlength="500" value="" autocomplete="off" data-server-history="ooba_streaming"> <input id="streaming_url_textgenerationwebui" type="text" class="text_pole wide100p" maxlength="500" value="" autocomplete="off" data-server-history="ooba_streaming">
</div> </div>

View File

@ -0,0 +1,25 @@
(function($) {
var Defaults = $.fn.select2.amd.require('select2/defaults');
$.extend(Defaults.defaults, {
searchInputPlaceholder: '',
searchInputCssClass: '',
});
var SearchDropdown = $.fn.select2.amd.require('select2/dropdown/search');
var _renderSearchDropdown = SearchDropdown.prototype.render;
SearchDropdown.prototype.render = function(decorated) {
// invoke parent method
var $rendered = _renderSearchDropdown.apply(this, Array.prototype.slice.apply(arguments));
this.$search.attr('placeholder', this.options.get('searchInputPlaceholder'));
this.$search.addClass(this.options.get('searchInputCssClass'));
return $rendered;
};
})(window.jQuery);

View File

@ -177,6 +177,7 @@ import {
import { applyLocale } from "./scripts/i18n.js"; import { applyLocale } from "./scripts/i18n.js";
import { getTokenCount, getTokenizerModel, saveTokenCache } from "./scripts/tokenizers.js"; import { getTokenCount, getTokenizerModel, saveTokenCache } from "./scripts/tokenizers.js";
import { initPersonas, selectCurrentPersona, setPersonaDescription } from "./scripts/personas.js"; import { initPersonas, selectCurrentPersona, setPersonaDescription } from "./scripts/personas.js";
import { loadMancerModels } from "./scripts/mancer-settings.js";
//exporting functions and vars for mods //exporting functions and vars for mods
export { export {
@ -5037,10 +5038,9 @@ export function setGenerationParamsFromPreset(preset) {
} }
if (preset.max_length !== undefined) { if (preset.max_length !== undefined) {
max_context = preset.max_length; const needsUnlock = preset.max_length > MAX_CONTEXT_DEFAULT;
const needsUnlock = max_context > MAX_CONTEXT_DEFAULT;
$('#max_context_unlocked').prop('checked', needsUnlock).trigger('change'); $('#max_context_unlocked').prop('checked', needsUnlock).trigger('change');
max_context = preset.max_length;
$("#max_context").val(max_context); $("#max_context").val(max_context);
$("#max_context_counter").text(`${max_context}`); $("#max_context_counter").text(`${max_context}`);
@ -7564,6 +7564,10 @@ jQuery(async function () {
api_use_mancer_webui = enabled; api_use_mancer_webui = enabled;
saveSettingsDebounced(); saveSettingsDebounced();
getStatus(); getStatus();
if (enabled) {
loadMancerModels();
}
}); });
$("#api_button_textgenerationwebui").click(async function (e) { $("#api_button_textgenerationwebui").click(async function (e) {

View File

@ -0,0 +1,73 @@
import { api_server_textgenerationwebui, getRequestHeaders, setGenerationParamsFromPreset } from "../script.js";
let models = [];
/**
* @param {string} modelId
*/
export function getMancerModelURL(modelId) {
return `https://neuro.mancer.tech/webui/${modelId}/api`;
}
export async function loadMancerModels() {
try {
const response = await fetch('/api/mancer/models', {
method: 'POST',
headers: getRequestHeaders(),
});
if (!response.ok) {
return;
}
const data = await response.json();
models = data;
$('#mancer_model').empty();
for (const model of data) {
const option = document.createElement('option');
option.value = model.id;
option.text = model.name;
option.selected = api_server_textgenerationwebui === getMancerModelURL(model.id);
$('#mancer_model').append(option);
}
} catch {
console.warn('Failed to load Mancer models');
}
}
function onMancerModelSelect() {
const modelId = String($('#mancer_model').val());
const url = getMancerModelURL(modelId);
$('#mancer_api_url_text').val(url);
$('#api_button_textgenerationwebui').trigger('click');
const context = models.find(x => x.id === modelId)?.context;
setGenerationParamsFromPreset({ max_length: context });
}
function getMancerModelTemplate(option) {
const model = models.find(x => x.id === option?.element?.value);
if (!option.id || !model) {
return option.text;
}
return $((`
<div class="flex-container flexFlowColumn">
<div><strong>${DOMPurify.sanitize(model.name)}</strong> | <span>${model.context} ctx</span></div>
<small>${DOMPurify.sanitize(model.description)}</small>
</div>
`));
}
jQuery(function () {
$('#mancer_model').on('change', onMancerModelSelect).select2({
placeholder: 'Select a model',
searchInputPlaceholder: 'Search models...',
searchInputCssClass: 'text_pole',
width: '100%',
templateResult: getMancerModelTemplate,
});
});

View File

@ -810,6 +810,31 @@ app.post("/getchat", jsonParser, function (request, response) {
} }
}); });
app.post("/api/mancer/models", jsonParser, async function (_req, res) {
try {
const response = await fetch('https://mancer.tech/internal/api/models');
const data = await response.json();
if (!response.ok) {
console.log('Mancer models endpoint is offline.');
return res.json([]);
}
if (!Array.isArray(data.models)) {
console.log('Mancer models response is not an array.')
return res.json([]);
}
const modelIds = data.models.map(x => x.id);
console.log('Mancer models available:', modelIds);
return res.json(data.models);
} catch (error) {
console.error(error);
return res.json([]);
}
});
// Only called for kobold and ooba/mancer // Only called for kobold and ooba/mancer
app.post("/getstatus", jsonParser, async function (request, response) { app.post("/getstatus", jsonParser, async function (request, response) {
if (!request.body) return response.sendStatus(400); if (!request.body) return response.sendStatus(400);
@ -4331,7 +4356,7 @@ app.post('/generate_horde', jsonParser, async (request, response) => {
}; };
if (request.header('Client-Agent') !== undefined) args.headers['Client-Agent'] = request.header('Client-Agent'); if (request.header('Client-Agent') !== undefined) args.headers['Client-Agent'] = request.header('Client-Agent');
console.log(args.body); console.log(request.body);
try { try {
const data = await postAsync(url, args); const data = await postAsync(url, args);
return response.send(data); return response.send(data);