Gemini: Fix cross-chunk parsing of multipart replies

39cfb35c1a4d1ae56811ef5c5afb4190bc2fc041

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

2 files changed, +7 -7Showing whitespace changes
public/scripts/openai.js+4 -4
@@ -2098,7 +2098,7 @@ function getStreamingReply(data) {
2098 if (oai_settings.chat_completion_source === chat_completion_sources.CLAUDE) {2098 if (oai_settings.chat_completion_source === chat_completion_sources.CLAUDE) {
2099 return data?.delta?.text || '';2099 return data?.delta?.text || '';
2100 } else if (oai_settings.chat_completion_source === chat_completion_sources.MAKERSUITE) {2100 } else if (oai_settings.chat_completion_source === chat_completion_sources.MAKERSUITE) {
2101 return data?.candidates?.[0]?.content?.parts?.[0]?.text || '';2101 return data?.candidates?.[0]?.content?.parts?.map(x => x.text)?.join('\n\n') || '';
2102 } else if (oai_settings.chat_completion_source === chat_completion_sources.COHERE) {2102 } else if (oai_settings.chat_completion_source === chat_completion_sources.COHERE) {
2103 return data?.delta?.message?.content?.text || data?.delta?.message?.tool_plan || '';2103 return data?.delta?.message?.content?.text || data?.delta?.message?.tool_plan || '';
2104 } else {2104 } else {
@@ -2110,7 +2110,7 @@ function getStreamingReply(data) {
2110 * parseChatCompletionLogprobs converts the response data returned from a chat2110 * parseChatCompletionLogprobs converts the response data returned from a chat
2111 * completions-like source into an array of TokenLogprobs found in the response.2111 * completions-like source into an array of TokenLogprobs found in the response.
2112 * @param {Object} data - response data from a chat completions-like source2112 * @param {Object} data - response data from a chat completions-like source
2113 * @returns {import('logprobs.js').TokenLogprobs[] | null} converted logprobs2113 * @returns {import('./logprobs.js').TokenLogprobs[] | null} converted logprobs
2114 */2114 */
2115function parseChatCompletionLogprobs(data) {2115function parseChatCompletionLogprobs(data) {
2116 if (!data) {2116 if (!data) {
@@ -2139,7 +2139,7 @@ function parseChatCompletionLogprobs(data) {
2139 * completion API and converts into the structure used by the Token Probabilities2139 * completion API and converts into the structure used by the Token Probabilities
2140 * view.2140 * view.
2141 * @param {{content: { token: string, logprob: number, top_logprobs: { token: string, logprob: number }[] }[]}} logprobs2141 * @param {{content: { token: string, logprob: number, top_logprobs: { token: string, logprob: number }[] }[]}} logprobs
2142 * @returns {import('logprobs.js').TokenLogprobs[] | null} converted logprobs2142 * @returns {import('./logprobs.js').TokenLogprobs[] | null} converted logprobs
2143 */2143 */
2144function parseOpenAIChatLogprobs(logprobs) {2144function parseOpenAIChatLogprobs(logprobs) {
2145 const { content } = logprobs ?? {};2145 const { content } = logprobs ?? {};
@@ -2167,7 +2167,7 @@ function parseOpenAIChatLogprobs(logprobs) {
2167 * completion API and converts into the structure used by the Token Probabilities2167 * completion API and converts into the structure used by the Token Probabilities
2168 * view.2168 * view.
2169 * @param {{tokens: string[], token_logprobs: number[], top_logprobs: { token: string, logprob: number }[][]}} logprobs2169 * @param {{tokens: string[], token_logprobs: number[], top_logprobs: { token: string, logprob: number }[][]}} logprobs
2170 * @returns {import('logprobs.js').TokenLogprobs[] | null} converted logprobs2170 * @returns {import('./logprobs.js').TokenLogprobs[] | null} converted logprobs
2171 */2171 */
2172function parseOpenAITextLogprobs(logprobs) {2172function parseOpenAITextLogprobs(logprobs) {
2173 const { tokens, token_logprobs, top_logprobs } = logprobs ?? {};2173 const { tokens, token_logprobs, top_logprobs } = logprobs ?? {};
src/endpoints/backends/chat-completions.js+3 -3
@@ -367,15 +367,15 @@ async function sendMakerSuiteRequest(request, response) {
367 }367 }
368368
369 const responseContent = candidates[0].content ?? candidates[0].output;369 const responseContent = candidates[0].content ?? candidates[0].output;
370 const responseText = typeof responseContent === 'string' ? responseContent : responseContent?.parts?.[0]?.text;370 console.log('Google AI Studio response:', responseContent);
371
372 const responseText = typeof responseContent === 'string' ? responseContent : responseContent?.parts?.map(part => part.text)?.join('\n\n');
371 if (!responseText) {373 if (!responseText) {
372 let message = 'Google AI Studio Candidate text empty';374 let message = 'Google AI Studio Candidate text empty';
373 console.log(message, generateResponseJson);375 console.log(message, generateResponseJson);
374 return response.send({ error: { message } });376 return response.send({ error: { message } });
375 }377 }
376378
377 console.log('Google AI Studio response:', responseText);
378
379 // Wrap it back to OAI format379 // Wrap it back to OAI format
380 const reply = { choices: [{ 'message': { 'content': responseText } }] };380 const reply = { choices: [{ 'message': { 'content': responseText } }] };
381 return response.send(reply);381 return response.send(reply);