@@ -1804,6 +1827,7 @@
+
+
+
diff --git a/public/script.js b/public/script.js
index 3bf214d3a..36582390c 100644
--- a/public/script.js
+++ b/public/script.js
@@ -2131,7 +2131,7 @@ function baseChatReplace(value, name1, name2) {
}
function isStreamingEnabled() {
- return ((main_api == 'openai' && oai_settings.stream_openai && oai_settings.chat_completion_source !== chat_completion_sources.SCALE)
+ return ((main_api == 'openai' && oai_settings.stream_openai && oai_settings.chat_completion_source !== chat_completion_sources.SCALE && oai_settings.chat_completion_source !== chat_completion_sources.AI21)
|| (main_api == 'kobold' && kai_settings.streaming_kobold && kai_settings.can_use_streaming)
|| (main_api == 'novel' && nai_settings.streaming_novel)
|| (main_api == 'textgenerationwebui' && textgenerationwebui_settings.streaming))
@@ -4738,6 +4738,7 @@ function changeMainAPI() {
case chat_completion_sources.WINDOWAI:
case chat_completion_sources.CLAUDE:
case chat_completion_sources.OPENAI:
+ case chat_completion_sources.AI21:
default:
setupChatCompletionPromptManager(oai_settings);
break;
@@ -7178,6 +7179,11 @@ function connectAPISlash(_, text) {
source: 'openrouter',
button: '#api_button_openai',
},
+ 'ai21': {
+ selected: 'openai',
+ source: 'ai21',
+ button: '#api_button_openai',
+ }
};
const apiConfig = apiMap[text];
@@ -7396,7 +7402,7 @@ $(document).ready(function () {
}
registerSlashCommand('dupe', DupeChar, [], "– duplicates the currently selected character", true, true);
- registerSlashCommand('api', connectAPISlash, [], "(kobold, horde, novel, ooba, oai, claude, windowai) – connect to an API", true, true);
+ registerSlashCommand('api', connectAPISlash, [], "(kobold, horde, novel, ooba, oai, claude, windowai, ai21) – connect to an API", true, true);
registerSlashCommand('impersonate', doImpersonate, ['imp'], "- calls an impersonation response", true, true);
registerSlashCommand('delchat', doDeleteChat, [], "- deletes the current chat", true, true);
registerSlashCommand('closechat', doCloseChat, [], "- closes the current chat", true, true);
diff --git a/public/scripts/RossAscends-mods.js b/public/scripts/RossAscends-mods.js
index adc17cec9..6d7ac3d75 100644
--- a/public/scripts/RossAscends-mods.js
+++ b/public/scripts/RossAscends-mods.js
@@ -478,6 +478,7 @@ function RA_autoconnect(PrevApi) {
|| (secret_state[SECRET_KEYS.SCALE] && oai_settings.chat_completion_source == chat_completion_sources.SCALE)
|| (oai_settings.chat_completion_source == chat_completion_sources.WINDOWAI)
|| (secret_state[SECRET_KEYS.OPENROUTER] && oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER)
+ || (secret_state[SECRET_KEYS.AI21] && oai_settings.chat_completion_source == chat_completion_sources.AI21)
) {
$("#api_button_openai").click();
}
diff --git a/public/scripts/openai.js b/public/scripts/openai.js
index ea710abcc..95067827e 100644
--- a/public/scripts/openai.js
+++ b/public/scripts/openai.js
@@ -113,9 +113,13 @@ const scale_max = 7900; // Probably more. Save some for the system prompt define
const claude_max = 8000; // We have a proper tokenizer, so theoretically could be larger (up to 9k)
const palm2_max = 7500; // The real context window is 8192, spare some for padding due to using turbo tokenizer
const claude_100k_max = 99000;
+let ai21_max = 9200; //can easily fit 9k gpt tokens because j2's tokenizer is efficient af
const unlocked_max = 100 * 1024;
const oai_max_temp = 2.0;
-const claude_max_temp = 1.0;
+const claude_max_temp = 1.0; //same as j2
+const j2_max_topk = 10.0;
+const j2_max_freq = 5.0;
+const j2_max_pres = 5.0;
const openrouter_website_model = 'OR_Website';
let biasCache = undefined;
@@ -161,13 +165,26 @@ export const chat_completion_sources = {
CLAUDE: 'claude',
SCALE: 'scale',
OPENROUTER: 'openrouter',
+ AI21: 'ai21',
};
+const prefixMap = selected_group ? {
+ assistant: "",
+ user: "",
+ system: "OOC: "
+ }
+ : {
+ assistant: "{{char}}:",
+ user: "{{user}}:",
+ system: ""
+ };
+
const default_settings = {
preset_settings_openai: 'Default',
temp_openai: 0.9,
freq_pen_openai: 0.7,
pres_pen_openai: 0.7,
+ count_pen: 0.0,
top_p_openai: 1.0,
top_k_openai: 0,
stream_openai: false,
@@ -188,6 +205,7 @@ const default_settings = {
wi_format: default_wi_format,
openai_model: 'gpt-3.5-turbo',
claude_model: 'claude-instant-v1',
+ ai21_model: 'j2-ultra',
windowai_model: '',
openrouter_model: openrouter_website_model,
jailbreak_system: false,
@@ -199,6 +217,7 @@ const default_settings = {
show_external_models: false,
proxy_password: '',
assistant_prefill: '',
+ use_ai21_tokenizer: false,
};
const oai_settings = {
@@ -206,6 +225,7 @@ const oai_settings = {
temp_openai: 1.0,
freq_pen_openai: 0,
pres_pen_openai: 0,
+ count_pen: 0.0,
top_p_openai: 1.0,
top_k_openai: 0,
stream_openai: false,
@@ -226,6 +246,7 @@ const oai_settings = {
wi_format: default_wi_format,
openai_model: 'gpt-3.5-turbo',
claude_model: 'claude-instant-v1',
+ ai21_model: 'j2-ultra',
windowai_model: '',
openrouter_model: openrouter_website_model,
jailbreak_system: false,
@@ -237,6 +258,7 @@ const oai_settings = {
show_external_models: false,
proxy_password: '',
assistant_prefill: '',
+ use_ai21_tokenizer: false,
};
let openai_setting_names;
@@ -973,6 +995,8 @@ function getChatCompletionModel() {
return '';
case chat_completion_sources.OPENROUTER:
return oai_settings.openrouter_model !== openrouter_website_model ? oai_settings.openrouter_model : null;
+ case chat_completion_sources.AI21:
+ return oai_settings.ai21_model;
default:
throw new Error(`Unknown chat completion source: ${oai_settings.chat_completion_source}`);
}
@@ -1054,10 +1078,19 @@ async function sendOpenAIRequest(type, openai_msgs_tosend, signal) {
const isClaude = oai_settings.chat_completion_source == chat_completion_sources.CLAUDE;
const isOpenRouter = oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER;
const isScale = oai_settings.chat_completion_source == chat_completion_sources.SCALE;
+ const isAI21 = oai_settings.chat_completion_source == chat_completion_sources.AI21;
const isTextCompletion = oai_settings.chat_completion_source == chat_completion_sources.OPENAI && (oai_settings.openai_model.startsWith('text-') || oai_settings.openai_model.startsWith('code-'));
- const stream = type !== 'quiet' && oai_settings.stream_openai && !isScale;
+ const stream = type !== 'quiet' && oai_settings.stream_openai && !isScale && !isAI21;
const isQuiet = type === 'quiet';
+ if(isAI21) {
+ const joinedMsgs = openai_msgs_tosend.reduce((acc, obj) => {
+ const prefix = prefixMap[obj.role];
+ return acc + (prefix ? (selected_group ? "\n" : prefix + " ") : "") + obj.content + "\n";
+ }, "");
+ openai_msgs_tosend = substituteParams(joinedMsgs);
+ }
+
// If we're using the window.ai extension, use that instead
// Doesn't support logit bias yet
if (oai_settings.chat_completion_source == chat_completion_sources.WINDOWAI) {
@@ -1113,6 +1146,13 @@ async function sendOpenAIRequest(type, openai_msgs_tosend, signal) {
generate_data['api_url_scale'] = oai_settings.api_url_scale;
}
+ if (isAI21) {
+ generate_data['use_ai21'] = true;
+ generate_data['top_k'] = parseFloat(oai_settings.top_k_openai);
+ generate_data['count_pen'] = parseFloat(oai_settings.count_pen);
+ generate_data['stop_tokens'] = [name1 + ':', 'prompt: [Start a new chat]'];
+ }
+
const generate_url = '/generate_openai';
const response = await fetch(generate_url, {
method: 'POST',
@@ -1303,6 +1343,7 @@ class TokenHandler {
}
function countTokens(messages, full = false) {
+ let shouldTokenizeAI21 = oai_settings.chat_completion_source === chat_completion_sources.AI21 && oai_settings.use_ai21_tokenizer;
let chatId = 'undefined';
try {
@@ -1335,12 +1376,13 @@ function countTokens(messages, full = false) {
if (typeof cachedCount === 'number') {
token_count += cachedCount;
}
- else {
+ else {
+ console.log(JSON.stringify([message]));
jQuery.ajax({
async: false,
type: 'POST', //
- url: `/tokenize_openai?model=${model}`,
+ url: shouldTokenizeAI21 ? '/tokenize_ai21' : `/tokenize_openai?model=${model}`,
data: JSON.stringify([message]),
dataType: "json",
contentType: "application/json",
@@ -1856,6 +1898,7 @@ function loadOpenAISettings(data, settings) {
oai_settings.temp_openai = settings.temp_openai ?? default_settings.temp_openai;
oai_settings.freq_pen_openai = settings.freq_pen_openai ?? default_settings.freq_pen_openai;
oai_settings.pres_pen_openai = settings.pres_pen_openai ?? default_settings.pres_pen_openai;
+ oai_settings.count_pen = settings.count_pen ?? default_settings.count_pen;
oai_settings.top_p_openai = settings.top_p_openai ?? default_settings.top_p_openai;
oai_settings.top_k_openai = settings.top_k_openai ?? default_settings.top_k_openai;
oai_settings.stream_openai = settings.stream_openai ?? default_settings.stream_openai;
@@ -1871,6 +1914,7 @@ function loadOpenAISettings(data, settings) {
oai_settings.claude_model = settings.claude_model ?? default_settings.claude_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.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.api_url_scale = settings.api_url_scale ?? default_settings.api_url_scale;
oai_settings.show_external_models = settings.show_external_models ?? default_settings.show_external_models;
@@ -1889,7 +1933,7 @@ function loadOpenAISettings(data, settings) {
if (settings.wrap_in_quotes !== undefined) oai_settings.wrap_in_quotes = !!settings.wrap_in_quotes;
if (settings.names_in_completion !== undefined) oai_settings.names_in_completion = !!settings.names_in_completion;
if (settings.openai_model !== undefined) oai_settings.openai_model = settings.openai_model;
-
+ if (settings.use_ai21_tokenizer !== undefined) oai_settings.use_ai21_tokenizer = !!settings.use_ai21_tokenizer;
$('#stream_toggle').prop('checked', oai_settings.stream_openai);
$('#api_url_scale').val(oai_settings.api_url_scale);
$('#openai_proxy_password').val(oai_settings.proxy_password);
@@ -1901,6 +1945,8 @@ function loadOpenAISettings(data, settings) {
$(`#model_claude_select option[value="${oai_settings.claude_model}"`).attr('selected', true);
$('#model_windowai_select').val(oai_settings.windowai_model);
$(`#model_windowai_select option[value="${oai_settings.windowai_model}"`).attr('selected', true);
+ $('#model_ai21_select').val(oai_settings.ai21_model);
+ $(`#model_ai21_select option[value="${oai_settings.ai21_model}"`).attr('selected', true);
$('#openai_max_context').val(oai_settings.openai_max_context);
$('#openai_max_context_counter').text(`${oai_settings.openai_max_context}`);
$('#model_openrouter_select').val(oai_settings.openrouter_model);
@@ -1916,7 +1962,7 @@ function loadOpenAISettings(data, settings) {
$('#legacy_streaming').prop('checked', oai_settings.legacy_streaming);
$('#openai_show_external_models').prop('checked', oai_settings.show_external_models);
$('#openai_external_category').toggle(oai_settings.show_external_models);
-
+ $('#use_ai21_tokenizer').prop('checked', oai_settings.use_ai21_tokenizer);
if (settings.impersonation_prompt !== undefined) oai_settings.impersonation_prompt = settings.impersonation_prompt;
$('#impersonation_prompt_textarea').val(oai_settings.impersonation_prompt);
@@ -1939,6 +1985,9 @@ function loadOpenAISettings(data, settings) {
$('#pres_pen_openai').val(oai_settings.pres_pen_openai);
$('#pres_pen_counter_openai').text(Number(oai_settings.pres_pen_openai).toFixed(2));
+ $('#count_pen').val(oai_settings.count_pen);
+ $('#count_pen_counter').text(Number(oai_settings.count_pen).toFixed(2));
+
$('#top_p_openai').val(oai_settings.top_p_openai);
$('#top_p_counter_openai').text(Number(oai_settings.top_p_openai).toFixed(2));
@@ -1981,7 +2030,7 @@ async function getStatusOpen() {
return resultCheckStatusOpen();
}
- if (oai_settings.chat_completion_source == chat_completion_sources.SCALE || oai_settings.chat_completion_source == chat_completion_sources.CLAUDE) {
+ if (oai_settings.chat_completion_source == chat_completion_sources.SCALE || oai_settings.chat_completion_source == chat_completion_sources.CLAUDE || oai_settings.chat_completion_source == chat_completion_sources.AI21) {
let status = 'Unable to verify key; press "Test Message" to validate.';
setOnlineStatus(status);
return resultCheckStatusOpen();
@@ -2078,9 +2127,11 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) {
claude_model: settings.claude_model,
windowai_model: settings.windowai_model,
openrouter_model: settings.openrouter_model,
+ ai21_model: settings.ai21_model,
temperature: settings.temp_openai,
frequency_penalty: settings.freq_pen_openai,
presence_penalty: settings.pres_pen_openai,
+ count_penalty: settings.count_pen,
top_p: settings.top_p_openai,
top_k: settings.top_k_openai,
openai_max_context: settings.openai_max_context,
@@ -2108,6 +2159,7 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) {
api_url_scale: settings.api_url_scale,
show_external_models: settings.show_external_models,
assistant_prefill: settings.assistant_prefill,
+ use_ai21_tokenizer: settings.use_ai21_tokenizer,
};
const savePresetSettings = await fetch(`/savepreset_openai?name=${name}`, {
@@ -2407,6 +2459,7 @@ function onSettingsPresetChange() {
temperature: ['#temp_openai', 'temp_openai', false],
frequency_penalty: ['#freq_pen_openai', 'freq_pen_openai', false],
presence_penalty: ['#pres_pen_openai', 'pres_pen_openai', false],
+ count_penalty: ['#count_pen', 'count_pen', false],
top_p: ['#top_p_openai', 'top_p_openai', false],
top_k: ['#top_k_openai', 'top_k_openai', false],
max_context_unlocked: ['#oai_max_context_unlocked', 'max_context_unlocked', true],
@@ -2414,6 +2467,7 @@ function onSettingsPresetChange() {
claude_model: ['#model_claude_select', 'claude_model', false],
windowai_model: ['#model_windowai_select', 'windowai_model', false],
openrouter_model: ['#model_openrouter_select', 'openrouter_model', false],
+ ai21_model: ['#model_ai21_select', 'ai21_model', false],
openai_max_context: ['#openai_max_context', 'openai_max_context', false],
openai_max_tokens: ['#openai_max_tokens', 'openai_max_tokens', false],
wrap_in_quotes: ['#wrap_in_quotes', 'wrap_in_quotes', true],
@@ -2437,6 +2491,7 @@ function onSettingsPresetChange() {
show_external_models: ['#openai_show_external_models', 'show_external_models', true],
proxy_password: ['#openai_proxy_password', 'proxy_password', false],
assistant_prefill: ['#claude_assistant_prefill', 'assistant_prefill', false],
+ use_ai21_tokenizer: ['#use_ai21_tokenizer', 'use_ai21_tokenizer', false],
};
const presetName = $('#settings_perset_openai').find(":selected").text();
@@ -2561,6 +2616,11 @@ async function onModelChange() {
oai_settings.openrouter_model = value;
}
+ if ($(this).is('#model_ai21_select')) {
+ console.log('AI21 model changed to', value);
+ oai_settings.ai21_model = value;
+ }
+
if (oai_settings.chat_completion_source == chat_completion_sources.SCALE) {
if (oai_settings.max_context_unlocked) {
$('#openai_max_context').attr('max', unlocked_max);
@@ -2647,6 +2707,38 @@ async function onModelChange() {
$('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input');
}
+ if (oai_settings.chat_completion_source == chat_completion_sources.AI21) {
+ if (oai_settings.max_context_unlocked) {
+ $('#openai_max_context').attr('max', unlocked_max);
+ } else {
+ $('#openai_max_context').attr('max', ai21_max);
+ }
+
+ oai_settings.openai_max_context = Math.min(oai_settings.openai_max_context, Number($('#openai_max_context').attr('max')));
+ $('#openai_max_context').val(oai_settings.openai_max_context).trigger('input');
+
+ oai_settings.temp_openai = Math.min(claude_max_temp, oai_settings.temp_openai);
+ $('#temp_openai').attr('max', claude_max_temp).val(oai_settings.temp_openai).trigger('input');
+
+ oai_settings.freq_pen_openai = Math.min(j2_max_freq, oai_settings.freq_pen_openai < 0 ? 0 : oai_settings.freq_pen_openai);
+ $('#freq_pen_openai').attr('min', 0).attr('max', j2_max_freq).val(oai_settings.freq_pen_openai).trigger('input');
+
+ oai_settings.pres_pen_openai = Math.min(j2_max_pres, oai_settings.pres_pen_openai < 0 ? 0 : oai_settings.pres_pen_openai);
+ $('#pres_pen_openai').attr('min', 0).attr('max', j2_max_pres).val(oai_settings.pres_pen_openai).trigger('input');
+
+ oai_settings.top_k_openai = Math.min(j2_max_topk, oai_settings.top_k_openai);
+ $('#top_k_openai').attr('max', j2_max_topk).val(oai_settings.top_k_openai).trigger('input');
+ } else if (oai_settings.chat_completion_source != chat_completion_sources.AI21) {
+ oai_settings.freq_pen_openai = Math.min(2.0, oai_settings.freq_pen_openai);
+ $('#freq_pen_openai').attr('min', -2.0).attr('max', 2.0).val(oai_settings.freq_pen_openai).trigger('input');
+
+ oai_settings.freq_pen_openai = Math.min(2.0, oai_settings.pres_pen_openai);
+ $('#pres_pen_openai').attr('min', -2.0).attr('max', 2.0).val(oai_settings.freq_pen_openai).trigger('input');
+
+ oai_settings.top_k_openai = Math.min(200, oai_settings.top_k_openai);
+ $('#top_k_openai').attr('max', 200).val(oai_settings.top_k_openai).trigger('input');
+ }
+
saveSettingsDebounced();
eventSource.emit(event_types.CHATCOMPLETION_MODEL_CHANGED, value);
}
@@ -2737,6 +2829,19 @@ async function onConnectButtonClick(e) {
}
}
+ if (oai_settings.chat_completion_source == chat_completion_sources.AI21) {
+ const api_key_ai21 = $('#api_key_ai21').val().trim();
+
+ if (api_key_ai21.length) {
+ await writeSecret(SECRET_KEYS.AI21, api_key_ai21);
+ }
+
+ if (!secret_state[SECRET_KEYS.AI21] && !oai_settings.reverse_proxy) {
+ console.log('No secret key saved for Claude');
+ return;
+ }
+ }
+
$("#api_loading_openai").css("display", 'inline-block');
$("#api_button_openai").css("display", 'none');
saveSettingsDebounced();
@@ -2766,7 +2871,9 @@ function toggleChatCompletionForms() {
else if (oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER) {
$('#model_openrouter_select').trigger('change');
}
-
+ else if (oai_settings.chat_completion_source == chat_completion_sources.AI21) {
+ $('#model_ai21_select').trigger('change');
+ }
$('[data-source]').each(function () {
const validSources = $(this).data('source').split(',');
$(this).toggle(validSources.includes(oai_settings.chat_completion_source));
@@ -2824,7 +2931,12 @@ $(document).ready(async function () {
oai_settings.pres_pen_openai = $(this).val();
$('#pres_pen_counter_openai').text(Number($(this).val()).toFixed(2));
saveSettingsDebounced();
+ });
+ $(document).on('input', '#count_pen', function () {
+ oai_settings.count_pen = $(this).val();
+ $('#count_pen_counter').text(Number($(this).val()).toFixed(2));
+ saveSettingsDebounced();
});
$(document).on('input', '#top_p_openai', function () {
@@ -2862,6 +2974,14 @@ $(document).ready(async function () {
saveSettingsDebounced();
});
+ $('#use_ai21_tokenizer').on('change', function () {
+ oai_settings.use_ai21_tokenizer = !!$('#use_ai21_tokenizer').prop('checked');
+ oai_settings.use_ai21_tokenizer ? ai21_max = 8191: ai21_max = 9200;
+ oai_settings.openai_max_context = Math.min(ai21_max, oai_settings.openai_max_context);
+ $('#openai_max_context').attr('max', ai21_max).val(oai_settings.openai_max_context).trigger('input');
+ saveSettingsDebounced();
+ });
+
$('#names_in_completion').on('change', function () {
oai_settings.names_in_completion = !!$('#names_in_completion').prop('checked');
saveSettingsDebounced();
@@ -3029,6 +3149,7 @@ $(document).ready(async function () {
$("#model_windowai_select").on("change", onModelChange);
$("#model_scale_select").on("change", onModelChange);
$("#model_openrouter_select").on("change", onModelChange);
+ $("#model_ai21_select").on("change", onModelChange);
$("#settings_perset_openai").on("change", onSettingsPresetChange);
$("#new_oai_preset").on("click", onNewPresetClick);
$("#delete_oai_preset").on("click", onDeletePresetClick);
diff --git a/public/scripts/secrets.js b/public/scripts/secrets.js
index 00203a106..202870c50 100644
--- a/public/scripts/secrets.js
+++ b/public/scripts/secrets.js
@@ -8,6 +8,7 @@ export const SECRET_KEYS = {
CLAUDE: 'api_key_claude',
OPENROUTER: 'api_key_openrouter',
SCALE: 'api_key_scale',
+ AI21: 'api_key_ai21',
}
const INPUT_MAP = {
@@ -18,6 +19,7 @@ const INPUT_MAP = {
[SECRET_KEYS.CLAUDE]: '#api_key_claude',
[SECRET_KEYS.OPENROUTER]: '#api_key_openrouter',
[SECRET_KEYS.SCALE]: '#api_key_scale',
+ [SECRET_KEYS.AI21]: '#api_key_ai21',
}
async function clearSecret() {
diff --git a/server.js b/server.js
index 67f62a249..1da4ea291 100644
--- a/server.js
+++ b/server.js
@@ -3323,6 +3323,10 @@ app.post("/generate_openai", jsonParser, function (request, response_generate_op
return sendScaleRequest(request, response_generate_openai);
}
+ if (request.body.use_ai21) {
+ return sendAI21Request(request, response_generate_openai);
+ }
+
let api_url;
let api_key_openai;
let headers;
@@ -3512,6 +3516,96 @@ app.post("/tokenize_openai", jsonParser, function (request, response_tokenize_op
response_tokenize_openai.send({ "token_count": num_tokens });
});
+async function sendAI21Request(request, response) {
+ if (!request.body) return response.sendStatus(400);
+ const controller = new AbortController();
+ console.log(request.body.messages)
+ request.socket.removeAllListeners('close');
+ request.socket.on('close', function () {
+ controller.abort();
+ });
+ //console.log(request.body)
+ const options = {
+ method: 'POST',
+ headers: {
+ accept: 'application/json',
+ 'content-type': 'application/json',
+ Authorization: `Bearer ${readSecret(SECRET_KEYS.AI21)}`
+ },
+ body: JSON.stringify({
+ numResults: 1,
+ maxTokens: request.body.max_tokens,
+ minTokens: 0,
+ temperature: request.body.temperature,
+ topP: request.body.top_p,
+ stopSequences: request.body.stop_tokens,
+ topKReturn: request.body.top_k,
+ frequencyPenalty: {
+ scale: request.body.frequency_penalty * 100,
+ applyToWhitespaces: false,
+ applyToPunctuations: false,
+ applyToNumbers: false,
+ applyToStopwords: false,
+ applyToEmojis: false
+ },
+ presencePenalty: {
+ scale: request.body.presence_penalty,
+ applyToWhitespaces: false,
+ applyToPunctuations: false,
+ applyToNumbers: false,
+ applyToStopwords: false,
+ applyToEmojis: false
+ },
+ countPenalty: {
+ scale: request.body.count_pen,
+ applyToWhitespaces: false,
+ applyToPunctuations: false,
+ applyToNumbers: false,
+ applyToStopwords: false,
+ applyToEmojis: false
+ },
+ prompt: request.body.messages
+ }),
+ signal: controller.signal,
+ };
+
+ fetch(`https://api.ai21.com/studio/v1/${request.body.model}/complete`, options)
+ .then(r => r.json())
+ .then(r => {
+ if (r.completions === undefined) {
+ console.log(r)
+ } else {
+ console.log(r.completions[0].data.text)
+ }
+ const reply = { choices: [{ "message": { "content": r.completions[0].data.text, } }] };
+ return response.send(reply)
+ })
+ .catch(err => {
+ console.error(err)
+ return response.send({error: true})
+ });
+
+}
+
+app.post("/tokenize_ai21", jsonParser, function (request, response_tokenize_ai21 = response) {
+ if (!request.body) return response_tokenize_ai21.sendStatus(400);
+ console.log(request.body[0].content)
+ const options = {
+ method: 'POST',
+ headers: {
+ accept: 'application/json',
+ 'content-type': 'application/json',
+ Authorization: `Bearer ${readSecret(SECRET_KEYS.AI21)}`
+ },
+ body: JSON.stringify({text: request.body[0].content})
+ };
+
+ fetch('https://api.ai21.com/studio/v1/tokenize', options)
+ .then(response => response.json())
+ .then(response => response_tokenize_ai21.send({"token_count": response.tokens.length}))
+ .catch(err => console.error(err));
+});
+
app.post("/save_preset", jsonParser, function (request, response) {
const name = sanitize(request.body.name);
if (!request.body.preset || !name) {
@@ -3825,6 +3919,7 @@ const SECRET_KEYS = {
DEEPL: 'deepl',
OPENROUTER: 'api_key_openrouter',
SCALE: 'api_key_scale',
+ AI21: 'api_key_ai21'
}
function migrateSecrets() {