From 6d79cc015ab8e9049a4b09b0d197c30aa709ef09 Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Fri, 13 Sep 2024 19:44:12 +0300
Subject: [PATCH 1/6] Add OpenAI o1
---
package-lock.json | 9 +++++----
package.json | 2 +-
public/index.html | 6 +++++-
public/script.js | 7 ++++++-
public/scripts/openai.js | 30 +++++++++++++++++++++++++++---
src/endpoints/tokenizers.js | 4 ++++
6 files changed, 48 insertions(+), 10 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index ca83e8446..abba30c5b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -46,7 +46,7 @@
"sanitize-filename": "^1.6.3",
"sillytavern-transformers": "2.14.6",
"simple-git": "^3.19.1",
- "tiktoken": "^1.0.15",
+ "tiktoken": "^1.0.16",
"vectra": "^0.2.2",
"wavefile": "^11.0.0",
"write-file-atomic": "^5.0.1",
@@ -5751,9 +5751,10 @@
"license": "MIT"
},
"node_modules/tiktoken": {
- "version": "1.0.15",
- "resolved": "https://registry.npmjs.org/tiktoken/-/tiktoken-1.0.15.tgz",
- "integrity": "sha512-sCsrq/vMWUSEW29CJLNmPvWxlVp7yh2tlkAjpJltIKqp5CKf98ZNpdeHRmAlPVFlGEbswDc6SmI8vz64W/qErw=="
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/tiktoken/-/tiktoken-1.0.16.tgz",
+ "integrity": "sha512-hRcORIGF2YlAgWx3nzrGJOrKSJwLoc81HpXmMQk89632XAgURc7IeV2FgQ2iXo9z/J96fCvpsHg2kWoHcbj9fg==",
+ "license": "MIT"
},
"node_modules/timm": {
"version": "1.7.1",
diff --git a/package.json b/package.json
index 87d7fa508..99526e2f1 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,7 @@
"sanitize-filename": "^1.6.3",
"sillytavern-transformers": "2.14.6",
"simple-git": "^3.19.1",
- "tiktoken": "^1.0.15",
+ "tiktoken": "^1.0.16",
"vectra": "^0.2.2",
"wavefile": "^11.0.0",
"write-file-atomic": "^5.0.1",
diff --git a/public/index.html b/public/index.html
index 6f8c87112..397781653 100644
--- a/public/index.html
+++ b/public/index.html
@@ -383,7 +383,7 @@
Max Response Length (tokens)
-
+
@@ -2611,6 +2611,10 @@
+
-
+
From 45cfc532b1fbd22f8107becc0a8c012bb0cfdf1e Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Fri, 13 Sep 2024 19:56:48 +0300
Subject: [PATCH 3/6] Redirect max_tokens to max_completion_tokens
---
public/scripts/openai.js | 2 ++
src/endpoints/backends/chat-completions.js | 1 +
2 files changed, 3 insertions(+)
diff --git a/public/scripts/openai.js b/public/scripts/openai.js
index bd86df72a..5455637e4 100644
--- a/public/scripts/openai.js
+++ b/public/scripts/openai.js
@@ -1970,6 +1970,8 @@ async function sendOpenAIRequest(type, messages, signal) {
msg.role = 'user';
}
});
+ generate_data.max_completion_tokens = generate_data.max_tokens;
+ delete generate_data.max_tokens;
delete generate_data.stream;
delete generate_data.logprobs;
delete generate_data.top_logprobs;
diff --git a/src/endpoints/backends/chat-completions.js b/src/endpoints/backends/chat-completions.js
index 1757b9e5f..88541d937 100644
--- a/src/endpoints/backends/chat-completions.js
+++ b/src/endpoints/backends/chat-completions.js
@@ -965,6 +965,7 @@ router.post('/generate', jsonParser, function (request, response) {
'model': request.body.model,
'temperature': request.body.temperature,
'max_tokens': request.body.max_tokens,
+ 'max_completion_tokens': request.body.max_completion_tokens,
'stream': request.body.stream,
'presence_penalty': request.body.presence_penalty,
'frequency_penalty': request.body.frequency_penalty,
From db2b3569422c934ff0603b071447d0a8da8c2bf4 Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Fri, 13 Sep 2024 20:47:41 +0300
Subject: [PATCH 4/6] Remove stop for o1
---
public/scripts/openai.js | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/public/scripts/openai.js b/public/scripts/openai.js
index 5455637e4..246766a46 100644
--- a/public/scripts/openai.js
+++ b/public/scripts/openai.js
@@ -1982,9 +1982,9 @@ async function sendOpenAIRequest(type, messages, signal) {
delete generate_data.presence_penalty;
delete generate_data.tools;
delete generate_data.tool_choice;
+ delete generate_data.stop;
// IDK if it supports it and I have no way to test it
// delete generate_data.logit_bias;
- // delete generate_data.stop;
}
await eventSource.emit(event_types.CHAT_COMPLETION_SETTINGS_READY, generate_data);
@@ -2134,7 +2134,6 @@ async function checkFunctionToolCalls(data) {
const args = toolCall.function;
console.log('Function tool call:', toolCall);
await eventSource.emit(event_types.LLM_FUNCTION_TOOL_CALL, args);
- data.allowEmptyResponse = true;
}
}
@@ -2148,7 +2147,6 @@ async function checkFunctionToolCalls(data) {
/** @type {FunctionToolCall} */
const args = { name: content.name, arguments: JSON.stringify(content.input) };
await eventSource.emit(event_types.LLM_FUNCTION_TOOL_CALL, args);
- data.allowEmptyResponse = true;
}
}
}
@@ -2163,7 +2161,6 @@ async function checkFunctionToolCalls(data) {
const args = { name: toolCall.name, arguments: JSON.stringify(toolCall.parameters) };
console.log('Function tool call:', toolCall);
await eventSource.emit(event_types.LLM_FUNCTION_TOOL_CALL, args);
- data.allowEmptyResponse = true;
}
}
}
From d99a5eba2ab2ac8b58c12442a09aa85a7adf5b2c Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Fri, 13 Sep 2024 20:52:34 +0300
Subject: [PATCH 5/6] Remove empty message looping
---
public/script.js | 83 ++++++++++++++++--------------------------------
1 file changed, 27 insertions(+), 56 deletions(-)
diff --git a/public/script.js b/public/script.js
index 8ab8daa36..6d9860278 100644
--- a/public/script.js
+++ b/public/script.js
@@ -881,7 +881,6 @@ let abortController;
//css
var css_send_form_display = $('
').css('display');
-const MAX_GENERATION_LOOPS = 5;
var kobold_horde_model = '';
@@ -2864,10 +2863,10 @@ export function isStreamingEnabled() {
const noStreamSources = [chat_completion_sources.SCALE];
return (
(main_api == 'openai' &&
- oai_settings.stream_openai &&
- !noStreamSources.includes(oai_settings.chat_completion_source) &&
- !(oai_settings.chat_completion_source == chat_completion_sources.OPENAI && oai_settings.openai_model.startsWith('o1-')) &&
- !(oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE && oai_settings.google_model.includes('bison')))
+ oai_settings.stream_openai &&
+ !noStreamSources.includes(oai_settings.chat_completion_source) &&
+ !(oai_settings.chat_completion_source == chat_completion_sources.OPENAI && oai_settings.openai_model.startsWith('o1-')) &&
+ !(oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE && oai_settings.google_model.includes('bison')))
|| (main_api == 'kobold' && kai_settings.streaming_kobold && kai_flags.can_use_streaming)
|| (main_api == 'novel' && nai_settings.streaming_novel)
|| (main_api == 'textgenerationwebui' && textgen_settings.streaming));
@@ -3342,11 +3341,11 @@ function removeLastMessage() {
* @param {GenerateOptions} options Generation options
* @param {boolean} dryRun Whether to actually generate a message or just assemble the prompt
* @returns {Promise
} Returns a promise that resolves when the text is done generating.
- * @typedef {{automatic_trigger?: boolean, force_name2?: boolean, quiet_prompt?: string, quietToLoud?: boolean, skipWIAN?: boolean, force_chid?: number, signal?: AbortSignal, quietImage?: string, maxLoops?: number, quietName?: string }} GenerateOptions
+ * @typedef {{automatic_trigger?: boolean, force_name2?: boolean, quiet_prompt?: string, quietToLoud?: boolean, skipWIAN?: boolean, force_chid?: number, signal?: AbortSignal, quietImage?: string, quietName?: string }} GenerateOptions
*/
-export async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, maxLoops, quietName } = {}, dryRun = false) {
+export async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, quietName } = {}, dryRun = false) {
console.log('Generate entered');
- await eventSource.emit(event_types.GENERATION_STARTED, type, { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, maxLoops }, dryRun);
+ await eventSource.emit(event_types.GENERATION_STARTED, type, { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage }, dryRun);
setGenerationProgress(0);
generation_started = new Date();
@@ -3408,7 +3407,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
if (selected_group && !is_group_generating) {
if (!dryRun) {
// Returns the promise that generateGroupWrapper returns; resolves when generation is done
- return generateGroupWrapper(false, type, { quiet_prompt, force_chid, signal: abortController.signal, quietImage, maxLoops });
+ return generateGroupWrapper(false, type, { quiet_prompt, force_chid, signal: abortController.signal, quietImage });
}
const characterIndexMap = new Map(characters.map((char, index) => [char.avatar, index]));
@@ -4440,53 +4439,30 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
const displayIncomplete = type === 'quiet' && !quietToLoud;
getMessage = cleanUpMessage(getMessage, isImpersonate, isContinue, displayIncomplete);
- if (getMessage.length > 0 || data.allowEmptyResponse) {
- if (isImpersonate) {
- $('#send_textarea').val(getMessage)[0].dispatchEvent(new Event('input', { bubbles: true }));
- generatedPromptCache = '';
- await eventSource.emit(event_types.IMPERSONATE_READY, getMessage);
- }
- else if (type == 'quiet') {
- unblockGeneration(type);
- return getMessage;
+ if (isImpersonate) {
+ $('#send_textarea').val(getMessage)[0].dispatchEvent(new Event('input', { bubbles: true }));
+ generatedPromptCache = '';
+ await eventSource.emit(event_types.IMPERSONATE_READY, getMessage);
+ }
+ else if (type == 'quiet') {
+ unblockGeneration(type);
+ return getMessage;
+ }
+ else {
+ // Without streaming we'll be having a full message on continuation. Treat it as a last chunk.
+ if (originalType !== 'continue') {
+ ({ type, getMessage } = await saveReply(type, getMessage, false, title, swipes));
}
else {
- // Without streaming we'll be having a full message on continuation. Treat it as a last chunk.
- if (originalType !== 'continue') {
- ({ type, getMessage } = await saveReply(type, getMessage, false, title, swipes));
- }
- else {
- ({ type, getMessage } = await saveReply('appendFinal', getMessage, false, title, swipes));
- }
-
- // This relies on `saveReply` having been called to add the message to the chat, so it must be last.
- parseAndSaveLogprobs(data, continue_mag);
+ ({ type, getMessage } = await saveReply('appendFinal', getMessage, false, title, swipes));
}
- if (type !== 'quiet') {
- playMessageSound();
- }
- } else {
- // If maxLoops is not passed in (e.g. first time generating), set it to MAX_GENERATION_LOOPS
- maxLoops ??= MAX_GENERATION_LOOPS;
+ // This relies on `saveReply` having been called to add the message to the chat, so it must be last.
+ parseAndSaveLogprobs(data, continue_mag);
+ }
- if (maxLoops === 0) {
- if (type !== 'quiet') {
- throwCircuitBreakerError();
- }
- throw new Error('Generate circuit breaker interruption');
- }
-
- // regenerate with character speech reenforced
- // to make sure we leave on swipe type while also adding the name2 appendage
- await delay(1000);
- // A message was already deleted on regeneration, so instead treat is as a normal gen
- if (type === 'regenerate') {
- type = 'normal';
- }
- // The first await is for waiting for the generate to start. The second one is waiting for it to finish
- const result = await await Generate(type, { automatic_trigger, force_name2: true, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, quietName, maxLoops: maxLoops - 1 });
- return result;
+ if (type !== 'quiet') {
+ playMessageSound();
}
if (power_user.auto_swipe) {
@@ -5259,11 +5235,6 @@ function getGenerateUrl(api) {
}
}
-function throwCircuitBreakerError() {
- callPopup(`Could not extract reply in ${MAX_GENERATION_LOOPS} attempts. Try generating again`, 'text');
- unblockGeneration();
-}
-
function extractTitleFromData(data) {
if (main_api == 'koboldhorde') {
return data.workerName;
From eeee2068879731a28a5442e7dbd0d1e6f0d4bfe6 Mon Sep 17 00:00:00 2001
From: Cohee <18619528+Cohee1207@users.noreply.github.com>
Date: Fri, 13 Sep 2024 21:03:04 +0300
Subject: [PATCH 6/6] Fix logit_bias comment
---
public/scripts/openai.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/public/scripts/openai.js b/public/scripts/openai.js
index 246766a46..0b86d8f5e 100644
--- a/public/scripts/openai.js
+++ b/public/scripts/openai.js
@@ -1983,7 +1983,7 @@ async function sendOpenAIRequest(type, messages, signal) {
delete generate_data.tools;
delete generate_data.tool_choice;
delete generate_data.stop;
- // IDK if it supports it and I have no way to test it
+ // It does support logit_bias, but the tokenizer used and its effect is yet unknown.
// delete generate_data.logit_bias;
}