Gemini: Thought toggle Closes #3220

662f0e9c732649e1f6766965c9e895ab0befd955

Cohee <18619528+Cohee1207@users.noreply.github.com>

4 files changed, +40 -3Showing whitespace changes
public/index.html+14 -0
@@ -1975,6 +1975,20 @@
1975 </span>1975 </span>
1976 </div>1976 </div>
1977 </div>1977 </div>
1978 <div class="range-block" data-source="makersuite">
1979 <label for="openai_show_thoughts" class="checkbox_label widthFreeExpand">
1980 <input id="openai_show_thoughts" type="checkbox" />
1981 <span>
1982 <span data-i18n="Show model thoughts">Show model thoughts</span>
1983 <i class="opacity50p fa-solid fa-circle-info" title="Gemini 2.0 Thinking"></i>
1984 </span>
1985 </label>
1986 <div class="toggle-description justifyLeft marginBot5">
1987 <span data-i18n="Display the model's internal thoughts in the response.">
1988 Display the model's internal thoughts in the response.
1989 </span>
1990 </div>
1991 </div>
1978 <div class="range-block" data-source="claude">1992 <div class="range-block" data-source="claude">
1979 <div class="wide100p">1993 <div class="wide100p">
1980 <div class="flex-container alignItemsCenter">1994 <div class="flex-container alignItemsCenter">
public/scripts/openai.js+13 -1
@@ -295,6 +295,7 @@ const default_settings = {
295 names_behavior: character_names_behavior.DEFAULT,295 names_behavior: character_names_behavior.DEFAULT,
296 continue_postfix: continue_postfix_types.SPACE,296 continue_postfix: continue_postfix_types.SPACE,
297 custom_prompt_post_processing: custom_prompt_post_processing_types.NONE,297 custom_prompt_post_processing: custom_prompt_post_processing_types.NONE,
298 show_thoughts: false,
298 seed: -1,299 seed: -1,
299 n: 1,300 n: 1,
300};301};
@@ -372,6 +373,7 @@ const oai_settings = {
372 names_behavior: character_names_behavior.DEFAULT,373 names_behavior: character_names_behavior.DEFAULT,
373 continue_postfix: continue_postfix_types.SPACE,374 continue_postfix: continue_postfix_types.SPACE,
374 custom_prompt_post_processing: custom_prompt_post_processing_types.NONE,375 custom_prompt_post_processing: custom_prompt_post_processing_types.NONE,
376 show_thoughts: false,
375 seed: -1,377 seed: -1,
376 n: 1,378 n: 1,
377};379};
@@ -1884,6 +1886,7 @@ async function sendOpenAIRequest(type, messages, signal) {
1884 'user_name': name1,1886 'user_name': name1,
1885 'char_name': name2,1887 'char_name': name2,
1886 'group_names': getGroupNames(),1888 'group_names': getGroupNames(),
1889 'show_thoughts': Boolean(oai_settings.show_thoughts),
1887 };1890 };
18881891
1889 // Empty array will produce a validation error1892 // Empty array will produce a validation error
@@ -2098,7 +2101,7 @@ function getStreamingReply(data) {
2098 if (oai_settings.chat_completion_source === chat_completion_sources.CLAUDE) {2101 if (oai_settings.chat_completion_source === chat_completion_sources.CLAUDE) {
2099 return data?.delta?.text || '';2102 return data?.delta?.text || '';
2100 } else if (oai_settings.chat_completion_source === chat_completion_sources.MAKERSUITE) {2103 } else if (oai_settings.chat_completion_source === chat_completion_sources.MAKERSUITE) {
2101 return data?.candidates?.[0]?.content?.parts?.map(x => x.text)?.join('\n\n') || '';2104 return data?.candidates?.[0]?.content?.parts?.filter(x => oai_settings.show_thoughts || !x.thought)?.map(x => x.text)?.filter(x => x)?.join('\n\n') || '';
2102 } else if (oai_settings.chat_completion_source === chat_completion_sources.COHERE) {2105 } else if (oai_settings.chat_completion_source === chat_completion_sources.COHERE) {
2103 return data?.delta?.message?.content?.text || data?.delta?.message?.tool_plan || '';2106 return data?.delta?.message?.content?.text || data?.delta?.message?.tool_plan || '';
2104 } else {2107 } else {
@@ -3056,6 +3059,7 @@ function loadOpenAISettings(data, settings) {
3056 oai_settings.image_inlining = settings.image_inlining ?? default_settings.image_inlining;3059 oai_settings.image_inlining = settings.image_inlining ?? default_settings.image_inlining;
3057 oai_settings.inline_image_quality = settings.inline_image_quality ?? default_settings.inline_image_quality;3060 oai_settings.inline_image_quality = settings.inline_image_quality ?? default_settings.inline_image_quality;
3058 oai_settings.bypass_status_check = settings.bypass_status_check ?? default_settings.bypass_status_check;3061 oai_settings.bypass_status_check = settings.bypass_status_check ?? default_settings.bypass_status_check;
3062 oai_settings.show_thoughts = settings.show_thoughts ?? default_settings.show_thoughts;
3059 oai_settings.seed = settings.seed ?? default_settings.seed;3063 oai_settings.seed = settings.seed ?? default_settings.seed;
3060 oai_settings.n = settings.n ?? default_settings.n;3064 oai_settings.n = settings.n ?? default_settings.n;
30613065
@@ -3181,6 +3185,7 @@ function loadOpenAISettings(data, settings) {
3181 $('#repetition_penalty_counter_openai').val(Number(oai_settings.repetition_penalty_openai));3185 $('#repetition_penalty_counter_openai').val(Number(oai_settings.repetition_penalty_openai));
3182 $('#seed_openai').val(oai_settings.seed);3186 $('#seed_openai').val(oai_settings.seed);
3183 $('#n_openai').val(oai_settings.n);3187 $('#n_openai').val(oai_settings.n);
3188 $('#openai_show_thoughts').prop('checked', oai_settings.show_thoughts);
31843189
3185 if (settings.reverse_proxy !== undefined) oai_settings.reverse_proxy = settings.reverse_proxy;3190 if (settings.reverse_proxy !== undefined) oai_settings.reverse_proxy = settings.reverse_proxy;
3186 $('#openai_reverse_proxy').val(oai_settings.reverse_proxy);3191 $('#openai_reverse_proxy').val(oai_settings.reverse_proxy);
@@ -3441,6 +3446,7 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) {
3441 continue_prefill: settings.continue_prefill,3446 continue_prefill: settings.continue_prefill,
3442 continue_postfix: settings.continue_postfix,3447 continue_postfix: settings.continue_postfix,
3443 function_calling: settings.function_calling,3448 function_calling: settings.function_calling,
3449 show_thoughts: settings.show_thoughts,
3444 seed: settings.seed,3450 seed: settings.seed,
3445 n: settings.n,3451 n: settings.n,
3446 };3452 };
@@ -3897,6 +3903,7 @@ function onSettingsPresetChange() {
3897 continue_prefill: ['#continue_prefill', 'continue_prefill', true],3903 continue_prefill: ['#continue_prefill', 'continue_prefill', true],
3898 continue_postfix: ['#continue_postfix', 'continue_postfix', false],3904 continue_postfix: ['#continue_postfix', 'continue_postfix', false],
3899 function_calling: ['#openai_function_calling', 'function_calling', true],3905 function_calling: ['#openai_function_calling', 'function_calling', true],
3906 show_thoughts: ['#openai_show_thoughts', 'show_thoughts', true],
3900 seed: ['#seed_openai', 'seed', false],3907 seed: ['#seed_openai', 'seed', false],
3901 n: ['#n_openai', 'n', false],3908 n: ['#n_openai', 'n', false],
3902 };3909 };
@@ -5390,6 +5397,11 @@ export function initOpenAI() {
5390 saveSettingsDebounced();5397 saveSettingsDebounced();
5391 });5398 });
53925399
5400 $('#openai_show_thoughts').on('input', function () {
5401 oai_settings.show_thoughts = !!$(this).prop('checked');
5402 saveSettingsDebounced();
5403 });
5404
5393 if (!CSS.supports('field-sizing', 'content')) {5405 if (!CSS.supports('field-sizing', 'content')) {
5394 $(document).on('input', '#openai_settings .autoSetHeight', function () {5406 $(document).on('input', '#openai_settings .autoSetHeight', function () {
5395 resetScrollHeight($(this));5407 resetScrollHeight($(this));
public/scripts/sse-stream.js+6 -1
@@ -144,9 +144,14 @@ async function* parseStreamData(json) {
144 for (let j = 0; j < json.candidates[i].content.parts.length; j++) {144 for (let j = 0; j < json.candidates[i].content.parts.length; j++) {
145 if (typeof json.candidates[i].content.parts[j].text === 'string') {145 if (typeof json.candidates[i].content.parts[j].text === 'string') {
146 for (let k = 0; k < json.candidates[i].content.parts[j].text.length; k++) {146 for (let k = 0; k < json.candidates[i].content.parts[j].text.length; k++) {
147 const str = json.candidates[i].content.parts[j].text[k];147 const moreThanOnePart = json.candidates[i].content.parts.length > 1;
148 const isNotLastPart = j !== json.candidates[i].content.parts.length - 1;
149 const isLastSymbol = k === json.candidates[i].content.parts[j].text.length - 1;
150 const addNewline = moreThanOnePart && isNotLastPart && isLastSymbol;
151 const str = json.candidates[i].content.parts[j].text[k] + (addNewline ? '\n\n' : '');
148 const candidateClone = structuredClone(json.candidates[0]);152 const candidateClone = structuredClone(json.candidates[0]);
149 candidateClone.content.parts[j].text = str;153 candidateClone.content.parts[j].text = str;
154 candidateClone.content.parts = [candidateClone.content.parts[j]];
150 const candidates = [candidateClone];155 const candidates = [candidateClone];
151 yield {156 yield {
152 data: { ...json, candidates },157 data: { ...json, candidates },
src/endpoints/backends/chat-completions.js+7 -1
@@ -278,6 +278,7 @@ async function sendMakerSuiteRequest(request, response) {
278278
279 const model = String(request.body.model);279 const model = String(request.body.model);
280 const stream = Boolean(request.body.stream);280 const stream = Boolean(request.body.stream);
281 const showThoughts = Boolean(request.body.show_thoughts);
281282
282 const generationConfig = {283 const generationConfig = {
283 stopSequences: request.body.stop,284 stopSequences: request.body.stop,
@@ -325,7 +326,8 @@ async function sendMakerSuiteRequest(request, response) {
325 controller.abort();326 controller.abort();
326 });327 });
327328
328 const apiVersion = 'v1beta';329 const isThinking = model.includes('thinking');
330 const apiVersion = isThinking ? 'v1alpha' : 'v1beta';
329 const responseType = (stream ? 'streamGenerateContent' : 'generateContent');331 const responseType = (stream ? 'streamGenerateContent' : 'generateContent');
330332
331 const generateResponse = await fetch(`${apiUrl.toString().replace(/\/$/, '')}/${apiVersion}/models/${model}:${responseType}?key=${apiKey}${stream ? '&alt=sse' : ''}`, {333 const generateResponse = await fetch(`${apiUrl.toString().replace(/\/$/, '')}/${apiVersion}/models/${model}:${responseType}?key=${apiKey}${stream ? '&alt=sse' : ''}`, {
@@ -369,6 +371,10 @@ async function sendMakerSuiteRequest(request, response) {
369 const responseContent = candidates[0].content ?? candidates[0].output;371 const responseContent = candidates[0].content ?? candidates[0].output;
370 console.log('Google AI Studio response:', responseContent);372 console.log('Google AI Studio response:', responseContent);
371373
374 if (Array.isArray(responseContent?.parts) && isThinking && !showThoughts) {
375 responseContent.parts = responseContent.parts.filter(part => !part.thought);
376 }
377
372 const responseText = typeof responseContent === 'string' ? responseContent : responseContent?.parts?.map(part => part.text)?.join('\n\n');378 const responseText = typeof responseContent === 'string' ? responseContent : responseContent?.parts?.map(part => part.text)?.join('\n\n');
373 if (!responseText) {379 if (!responseText) {
374 let message = 'Google AI Studio Candidate text empty';380 let message = 'Google AI Studio Candidate text empty';