mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge pull request #3625 from SillyTavern/gemini-search
Add backend-provided websearch connectors for OpenRouter and Gemini
This commit is contained in:
@@ -1951,7 +1951,18 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="range-block" data-source="openai,cohere,mistralai,custom,claude,openrouter,groq,deepseek">
|
<div class="range-block" data-source="makersuite,openrouter">
|
||||||
|
<label for="openai_enable_web_search" class="checkbox_label flexWrap widthFreeExpand">
|
||||||
|
<input id="openai_enable_web_search" type="checkbox" />
|
||||||
|
<span data-i18n="Enable web search">Enable web search</span>
|
||||||
|
</label>
|
||||||
|
<div class="flexBasis100p toggle-description justifyLeft">
|
||||||
|
<span>
|
||||||
|
Use search capabilities provided by the backend.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="range-block" data-source="openai,cohere,mistralai,custom,claude,openrouter,groq,deepseek,makersuite">
|
||||||
<label for="openai_function_calling" class="checkbox_label flexWrap widthFreeExpand">
|
<label for="openai_function_calling" class="checkbox_label flexWrap widthFreeExpand">
|
||||||
<input id="openai_function_calling" type="checkbox" />
|
<input id="openai_function_calling" type="checkbox" />
|
||||||
<span data-i18n="Enable function calling">Enable function calling</span>
|
<span data-i18n="Enable function calling">Enable function calling</span>
|
||||||
|
@@ -300,6 +300,7 @@ export const settingsToUpdate = {
|
|||||||
function_calling: ['#openai_function_calling', 'function_calling', true],
|
function_calling: ['#openai_function_calling', 'function_calling', true],
|
||||||
show_thoughts: ['#openai_show_thoughts', 'show_thoughts', true],
|
show_thoughts: ['#openai_show_thoughts', 'show_thoughts', true],
|
||||||
reasoning_effort: ['#openai_reasoning_effort', 'reasoning_effort', false],
|
reasoning_effort: ['#openai_reasoning_effort', 'reasoning_effort', false],
|
||||||
|
enable_web_search: ['#openai_enable_web_search', 'enable_web_search', true],
|
||||||
seed: ['#seed_openai', 'seed', false],
|
seed: ['#seed_openai', 'seed', false],
|
||||||
n: ['#n_openai', 'n', false],
|
n: ['#n_openai', 'n', false],
|
||||||
bypass_status_check: ['#openai_bypass_status_check', 'bypass_status_check', true],
|
bypass_status_check: ['#openai_bypass_status_check', 'bypass_status_check', true],
|
||||||
@@ -380,6 +381,7 @@ const default_settings = {
|
|||||||
custom_prompt_post_processing: custom_prompt_post_processing_types.NONE,
|
custom_prompt_post_processing: custom_prompt_post_processing_types.NONE,
|
||||||
show_thoughts: true,
|
show_thoughts: true,
|
||||||
reasoning_effort: 'medium',
|
reasoning_effort: 'medium',
|
||||||
|
enable_web_search: false,
|
||||||
seed: -1,
|
seed: -1,
|
||||||
n: 1,
|
n: 1,
|
||||||
};
|
};
|
||||||
@@ -459,6 +461,7 @@ const oai_settings = {
|
|||||||
custom_prompt_post_processing: custom_prompt_post_processing_types.NONE,
|
custom_prompt_post_processing: custom_prompt_post_processing_types.NONE,
|
||||||
show_thoughts: true,
|
show_thoughts: true,
|
||||||
reasoning_effort: 'medium',
|
reasoning_effort: 'medium',
|
||||||
|
enable_web_search: false,
|
||||||
seed: -1,
|
seed: -1,
|
||||||
n: 1,
|
n: 1,
|
||||||
};
|
};
|
||||||
@@ -2000,6 +2003,7 @@ async function sendOpenAIRequest(type, messages, signal) {
|
|||||||
'group_names': getGroupNames(),
|
'group_names': getGroupNames(),
|
||||||
'include_reasoning': Boolean(oai_settings.show_thoughts),
|
'include_reasoning': Boolean(oai_settings.show_thoughts),
|
||||||
'reasoning_effort': String(oai_settings.reasoning_effort),
|
'reasoning_effort': String(oai_settings.reasoning_effort),
|
||||||
|
'enable_web_search': Boolean(oai_settings.enable_web_search),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!canMultiSwipe && ToolManager.canPerformToolCalls(type)) {
|
if (!canMultiSwipe && ToolManager.canPerformToolCalls(type)) {
|
||||||
@@ -3222,6 +3226,7 @@ function loadOpenAISettings(data, settings) {
|
|||||||
oai_settings.bypass_status_check = settings.bypass_status_check ?? default_settings.bypass_status_check;
|
oai_settings.bypass_status_check = settings.bypass_status_check ?? default_settings.bypass_status_check;
|
||||||
oai_settings.show_thoughts = settings.show_thoughts ?? default_settings.show_thoughts;
|
oai_settings.show_thoughts = settings.show_thoughts ?? default_settings.show_thoughts;
|
||||||
oai_settings.reasoning_effort = settings.reasoning_effort ?? default_settings.reasoning_effort;
|
oai_settings.reasoning_effort = settings.reasoning_effort ?? default_settings.reasoning_effort;
|
||||||
|
oai_settings.enable_web_search = settings.enable_web_search ?? default_settings.enable_web_search;
|
||||||
oai_settings.seed = settings.seed ?? default_settings.seed;
|
oai_settings.seed = settings.seed ?? default_settings.seed;
|
||||||
oai_settings.n = settings.n ?? default_settings.n;
|
oai_settings.n = settings.n ?? default_settings.n;
|
||||||
|
|
||||||
@@ -3349,6 +3354,7 @@ function loadOpenAISettings(data, settings) {
|
|||||||
$('#seed_openai').val(oai_settings.seed);
|
$('#seed_openai').val(oai_settings.seed);
|
||||||
$('#n_openai').val(oai_settings.n);
|
$('#n_openai').val(oai_settings.n);
|
||||||
$('#openai_show_thoughts').prop('checked', oai_settings.show_thoughts);
|
$('#openai_show_thoughts').prop('checked', oai_settings.show_thoughts);
|
||||||
|
$('#openai_enable_web_search').prop('checked', oai_settings.enable_web_search);
|
||||||
|
|
||||||
$('#openai_reasoning_effort').val(oai_settings.reasoning_effort);
|
$('#openai_reasoning_effort').val(oai_settings.reasoning_effort);
|
||||||
$(`#openai_reasoning_effort option[value="${oai_settings.reasoning_effort}"]`).prop('selected', true);
|
$(`#openai_reasoning_effort option[value="${oai_settings.reasoning_effort}"]`).prop('selected', true);
|
||||||
@@ -3613,6 +3619,7 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) {
|
|||||||
function_calling: settings.function_calling,
|
function_calling: settings.function_calling,
|
||||||
show_thoughts: settings.show_thoughts,
|
show_thoughts: settings.show_thoughts,
|
||||||
reasoning_effort: settings.reasoning_effort,
|
reasoning_effort: settings.reasoning_effort,
|
||||||
|
enable_web_search: settings.enable_web_search,
|
||||||
seed: settings.seed,
|
seed: settings.seed,
|
||||||
n: settings.n,
|
n: settings.n,
|
||||||
};
|
};
|
||||||
@@ -5572,6 +5579,11 @@ export function initOpenAI() {
|
|||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#openai_enable_web_search').on('input', function () {
|
||||||
|
oai_settings.enable_web_search = !!$(this).prop('checked');
|
||||||
|
saveSettingsDebounced();
|
||||||
|
});
|
||||||
|
|
||||||
if (!CSS.supports('field-sizing', 'content')) {
|
if (!CSS.supports('field-sizing', 'content')) {
|
||||||
$(document).on('input', '#openai_settings .autoSetHeight', function () {
|
$(document).on('input', '#openai_settings .autoSetHeight', function () {
|
||||||
resetScrollHeight($(this));
|
resetScrollHeight($(this));
|
||||||
|
@@ -137,9 +137,14 @@ async function* parseStreamData(json) {
|
|||||||
else if (Array.isArray(json.candidates)) {
|
else if (Array.isArray(json.candidates)) {
|
||||||
for (let i = 0; i < json.candidates.length; i++) {
|
for (let i = 0; i < json.candidates.length; i++) {
|
||||||
const isNotPrimary = json.candidates?.[0]?.index > 0;
|
const isNotPrimary = json.candidates?.[0]?.index > 0;
|
||||||
|
const hasToolCalls = json?.candidates?.[0]?.content?.parts?.some(p => p?.functionCall);
|
||||||
if (isNotPrimary || json.candidates.length === 0) {
|
if (isNotPrimary || json.candidates.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (hasToolCalls) {
|
||||||
|
yield { data: json, chunk: '' };
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (typeof json.candidates[0].content === 'object' && Array.isArray(json.candidates[i].content.parts)) {
|
if (typeof json.candidates[0].content === 'object' && Array.isArray(json.candidates[i].content.parts)) {
|
||||||
for (let j = 0; j < json.candidates[i].content.parts.length; j++) {
|
for (let j = 0; j < json.candidates[i].content.parts.length; j++) {
|
||||||
if (typeof json.candidates[i].content.parts[j].text === 'string') {
|
if (typeof json.candidates[i].content.parts[j].text === 'string') {
|
||||||
|
@@ -506,6 +506,26 @@ export class ToolManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (Array.isArray(parsed?.candidates)) {
|
||||||
|
for (let choiceIndex = 0; choiceIndex < parsed.candidates.length; choiceIndex++) {
|
||||||
|
const candidate = parsed.candidates[choiceIndex];
|
||||||
|
if (Array.isArray(candidate?.content?.parts)) {
|
||||||
|
for (let toolCallIndex = 0; toolCallIndex < candidate.content.parts.length; toolCallIndex++) {
|
||||||
|
const part = candidate.content.parts[toolCallIndex];
|
||||||
|
if (part.functionCall) {
|
||||||
|
if (!Array.isArray(toolCalls[choiceIndex])) {
|
||||||
|
toolCalls[choiceIndex] = [];
|
||||||
|
}
|
||||||
|
if (toolCalls[choiceIndex][toolCallIndex] === undefined) {
|
||||||
|
toolCalls[choiceIndex][toolCallIndex] = {};
|
||||||
|
}
|
||||||
|
const targetToolCall = toolCalls[choiceIndex][toolCallIndex];
|
||||||
|
ToolManager.#applyToolCallDelta(targetToolCall, part.functionCall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -564,6 +584,7 @@ export class ToolManager {
|
|||||||
chat_completion_sources.GROQ,
|
chat_completion_sources.GROQ,
|
||||||
chat_completion_sources.COHERE,
|
chat_completion_sources.COHERE,
|
||||||
chat_completion_sources.DEEPSEEK,
|
chat_completion_sources.DEEPSEEK,
|
||||||
|
chat_completion_sources.MAKERSUITE,
|
||||||
];
|
];
|
||||||
return supportedSources.includes(oai_settings.chat_completion_source);
|
return supportedSources.includes(oai_settings.chat_completion_source);
|
||||||
}
|
}
|
||||||
@@ -585,8 +606,11 @@ export class ToolManager {
|
|||||||
* @returns {any[]} Tool calls from the response data
|
* @returns {any[]} Tool calls from the response data
|
||||||
*/
|
*/
|
||||||
static #getToolCallsFromData(data) {
|
static #getToolCallsFromData(data) {
|
||||||
|
const getRandomId = () => Math.random().toString(36).substring(2);
|
||||||
const isClaudeToolCall = c => Array.isArray(c) ? c.filter(x => x).every(isClaudeToolCall) : c?.input && c?.name && c?.id;
|
const isClaudeToolCall = c => Array.isArray(c) ? c.filter(x => x).every(isClaudeToolCall) : c?.input && c?.name && c?.id;
|
||||||
|
const isGoogleToolCall = c => Array.isArray(c) ? c.filter(x => x).every(isGoogleToolCall) : c?.name && c?.args;
|
||||||
const convertClaudeToolCall = c => ({ id: c.id, function: { name: c.name, arguments: c.input } });
|
const convertClaudeToolCall = c => ({ id: c.id, function: { name: c.name, arguments: c.input } });
|
||||||
|
const convertGoogleToolCall = (c) => ({ id: getRandomId(), function: { name: c.name, arguments: c.args } });
|
||||||
|
|
||||||
// Parsed tool calls from streaming data
|
// Parsed tool calls from streaming data
|
||||||
if (Array.isArray(data) && data.length > 0 && Array.isArray(data[0])) {
|
if (Array.isArray(data) && data.length > 0 && Array.isArray(data[0])) {
|
||||||
@@ -594,6 +618,10 @@ export class ToolManager {
|
|||||||
return data[0].filter(x => x).map(convertClaudeToolCall);
|
return data[0].filter(x => x).map(convertClaudeToolCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isGoogleToolCall(data[0])) {
|
||||||
|
return data[0].filter(x => x).map(convertGoogleToolCall);
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof data[0]?.[0]?.tool_calls === 'object') {
|
if (typeof data[0]?.[0]?.tool_calls === 'object') {
|
||||||
return Array.isArray(data[0]?.[0]?.tool_calls) ? data[0][0].tool_calls : [data[0][0].tool_calls];
|
return Array.isArray(data[0]?.[0]?.tool_calls) ? data[0][0].tool_calls : [data[0][0].tool_calls];
|
||||||
}
|
}
|
||||||
@@ -601,6 +629,11 @@ export class ToolManager {
|
|||||||
return data[0];
|
return data[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Google AI Studio tool calls
|
||||||
|
if (Array.isArray(data?.responseContent?.parts)) {
|
||||||
|
return data.responseContent.parts.filter(p => p.functionCall).map(p => convertGoogleToolCall(p.functionCall));
|
||||||
|
}
|
||||||
|
|
||||||
// Parsed tool calls from non-streaming data
|
// Parsed tool calls from non-streaming data
|
||||||
if (Array.isArray(data?.choices)) {
|
if (Array.isArray(data?.choices)) {
|
||||||
// Find a choice with 0-index
|
// Find a choice with 0-index
|
||||||
|
@@ -98,6 +98,21 @@ function getOpenRouterTransforms(request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets OpenRouter plugins based on the request.
|
||||||
|
* @param {import('express').Request} request
|
||||||
|
* @returns {any[]} OpenRouter plugins
|
||||||
|
*/
|
||||||
|
function getOpenRouterPlugins(request) {
|
||||||
|
const plugins = [];
|
||||||
|
|
||||||
|
if (request.body.enable_web_search) {
|
||||||
|
plugins.push({ 'id': 'web' });
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugins;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a request to Claude API.
|
* Sends a request to Claude API.
|
||||||
* @param {express.Request} request Express request
|
* @param {express.Request} request Express request
|
||||||
@@ -323,6 +338,7 @@ async function sendMakerSuiteRequest(request, response) {
|
|||||||
|
|
||||||
const model = String(request.body.model);
|
const model = String(request.body.model);
|
||||||
const stream = Boolean(request.body.stream);
|
const stream = Boolean(request.body.stream);
|
||||||
|
const enableWebSearch = Boolean(request.body.enable_web_search);
|
||||||
const isThinking = model.includes('thinking');
|
const isThinking = model.includes('thinking');
|
||||||
|
|
||||||
const generationConfig = {
|
const generationConfig = {
|
||||||
@@ -348,6 +364,7 @@ async function sendMakerSuiteRequest(request, response) {
|
|||||||
model.startsWith('gemini-exp')
|
model.startsWith('gemini-exp')
|
||||||
) && request.body.use_makersuite_sysprompt;
|
) && request.body.use_makersuite_sysprompt;
|
||||||
|
|
||||||
|
const tools = [];
|
||||||
const prompt = convertGooglePrompt(request.body.messages, model, should_use_system_prompt, getPromptNames(request));
|
const prompt = convertGooglePrompt(request.body.messages, model, should_use_system_prompt, getPromptNames(request));
|
||||||
let safetySettings = GEMINI_SAFETY;
|
let safetySettings = GEMINI_SAFETY;
|
||||||
|
|
||||||
@@ -361,6 +378,26 @@ async function sendMakerSuiteRequest(request, response) {
|
|||||||
}
|
}
|
||||||
// Most of the other models allow for setting the threshold of filters, except for HARM_CATEGORY_CIVIC_INTEGRITY, to OFF.
|
// Most of the other models allow for setting the threshold of filters, except for HARM_CATEGORY_CIVIC_INTEGRITY, to OFF.
|
||||||
|
|
||||||
|
if (enableWebSearch) {
|
||||||
|
const searchTool = model.includes('1.5') || model.includes('1.0')
|
||||||
|
? ({ google_search_retrieval: {} })
|
||||||
|
: ({ google_search: {} });
|
||||||
|
tools.push(searchTool);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(request.body.tools) && request.body.tools.length > 0) {
|
||||||
|
const functionDeclarations = [];
|
||||||
|
for (const tool of request.body.tools) {
|
||||||
|
if (tool.type === 'function') {
|
||||||
|
if (tool.function.parameters?.$schema) {
|
||||||
|
delete tool.function.parameters.$schema;
|
||||||
|
}
|
||||||
|
functionDeclarations.push(tool.function);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tools.push({ function_declarations: functionDeclarations });
|
||||||
|
}
|
||||||
|
|
||||||
let body = {
|
let body = {
|
||||||
contents: prompt.contents,
|
contents: prompt.contents,
|
||||||
safetySettings: safetySettings,
|
safetySettings: safetySettings,
|
||||||
@@ -371,6 +408,10 @@ async function sendMakerSuiteRequest(request, response) {
|
|||||||
body.systemInstruction = prompt.system_instruction;
|
body.systemInstruction = prompt.system_instruction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tools.length) {
|
||||||
|
body.tools = tools;
|
||||||
|
}
|
||||||
|
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,10 +467,11 @@ async function sendMakerSuiteRequest(request, response) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const responseContent = candidates[0].content ?? candidates[0].output;
|
const responseContent = candidates[0].content ?? candidates[0].output;
|
||||||
|
const functionCall = (candidates?.[0]?.content?.parts ?? []).some(part => part.functionCall);
|
||||||
console.warn('Google AI Studio response:', responseContent);
|
console.warn('Google AI Studio response:', responseContent);
|
||||||
|
|
||||||
const responseText = typeof responseContent === 'string' ? responseContent : responseContent?.parts?.filter(part => !part.thought)?.map(part => part.text)?.join('\n\n');
|
const responseText = typeof responseContent === 'string' ? responseContent : responseContent?.parts?.filter(part => !part.thought)?.map(part => part.text)?.join('\n\n');
|
||||||
if (!responseText) {
|
if (!responseText && !functionCall) {
|
||||||
let message = 'Google AI Studio Candidate text empty';
|
let message = 'Google AI Studio Candidate text empty';
|
||||||
console.warn(message, generateResponseJson);
|
console.warn(message, generateResponseJson);
|
||||||
return response.send({ error: { message } });
|
return response.send({ error: { message } });
|
||||||
@@ -1014,6 +1056,7 @@ router.post('/generate', jsonParser, function (request, response) {
|
|||||||
headers = { ...OPENROUTER_HEADERS };
|
headers = { ...OPENROUTER_HEADERS };
|
||||||
bodyParams = {
|
bodyParams = {
|
||||||
'transforms': getOpenRouterTransforms(request),
|
'transforms': getOpenRouterTransforms(request),
|
||||||
|
'plugins': getOpenRouterPlugins(request),
|
||||||
'include_reasoning': Boolean(request.body.include_reasoning),
|
'include_reasoning': Boolean(request.body.include_reasoning),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import crypto from 'node:crypto';
|
import crypto from 'node:crypto';
|
||||||
import { getConfigValue } from './util.js';
|
import { getConfigValue, tryParse } from './util.js';
|
||||||
|
|
||||||
const PROMPT_PLACEHOLDER = getConfigValue('promptPlaceholder', 'Let\'s get started.');
|
const PROMPT_PLACEHOLDER = getConfigValue('promptPlaceholder', 'Let\'s get started.');
|
||||||
|
|
||||||
@@ -411,11 +411,12 @@ export function convertGooglePrompt(messages, model, useSysPrompt, names) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const system_instruction = { parts: { text: sys_prompt.trim() } };
|
const system_instruction = { parts: { text: sys_prompt.trim() } };
|
||||||
|
const toolNameMap = {};
|
||||||
|
|
||||||
const contents = [];
|
const contents = [];
|
||||||
messages.forEach((message, index) => {
|
messages.forEach((message, index) => {
|
||||||
// fix the roles
|
// fix the roles
|
||||||
if (message.role === 'system') {
|
if (message.role === 'system' || message.role === 'tool') {
|
||||||
message.role = 'user';
|
message.role = 'user';
|
||||||
} else if (message.role === 'assistant') {
|
} else if (message.role === 'assistant') {
|
||||||
message.role = 'model';
|
message.role = 'model';
|
||||||
@@ -423,7 +424,21 @@ export function convertGooglePrompt(messages, model, useSysPrompt, names) {
|
|||||||
|
|
||||||
// Convert the content to an array of parts
|
// Convert the content to an array of parts
|
||||||
if (!Array.isArray(message.content)) {
|
if (!Array.isArray(message.content)) {
|
||||||
message.content = [{ type: 'text', text: String(message.content ?? '') }];
|
const content = (() => {
|
||||||
|
const hasToolCalls = Array.isArray(message.tool_calls) && message.tool_calls.length > 0;
|
||||||
|
const hasToolCallId = typeof message.tool_call_id === 'string' && message.tool_call_id.length > 0;
|
||||||
|
|
||||||
|
if (hasToolCalls) {
|
||||||
|
return { type: 'tool_calls', tool_calls: message.tool_calls };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasToolCallId) {
|
||||||
|
return { type: 'tool_call_id', tool_call_id: message.tool_call_id, content: String(message.content ?? '') };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { type: 'text', text: String(message.content ?? '') };
|
||||||
|
})();
|
||||||
|
message.content = [content];
|
||||||
}
|
}
|
||||||
|
|
||||||
// similar story as claude
|
// similar story as claude
|
||||||
@@ -455,6 +470,25 @@ export function convertGooglePrompt(messages, model, useSysPrompt, names) {
|
|||||||
message.content.forEach((part) => {
|
message.content.forEach((part) => {
|
||||||
if (part.type === 'text') {
|
if (part.type === 'text') {
|
||||||
parts.push({ text: part.text });
|
parts.push({ text: part.text });
|
||||||
|
} else if (part.type === 'tool_call_id') {
|
||||||
|
const name = toolNameMap[part.tool_call_id] ?? 'unknown';
|
||||||
|
parts.push({
|
||||||
|
functionResponse: {
|
||||||
|
name: name,
|
||||||
|
response: { name: name, content: part.content },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else if (part.type === 'tool_calls') {
|
||||||
|
part.tool_calls.forEach((toolCall) => {
|
||||||
|
parts.push({
|
||||||
|
functionCall: {
|
||||||
|
name: toolCall.function.name,
|
||||||
|
args: tryParse(toolCall.function.arguments) ?? toolCall.function.arguments,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
toolNameMap[toolCall.id] = toolCall.function.name;
|
||||||
|
});
|
||||||
} else if (part.type === 'image_url' && isMultimodal) {
|
} else if (part.type === 'image_url' && isMultimodal) {
|
||||||
const mimeType = part.image_url.url.split(';')[0].split(':')[1];
|
const mimeType = part.image_url.url.split(';')[0].split(':')[1];
|
||||||
const base64Data = part.image_url.url.split(',')[1];
|
const base64Data = part.image_url.url.split(',')[1];
|
||||||
@@ -473,7 +507,7 @@ export function convertGooglePrompt(messages, model, useSysPrompt, names) {
|
|||||||
if (part.text) {
|
if (part.text) {
|
||||||
contents[contents.length - 1].parts[0].text += '\n\n' + part.text;
|
contents[contents.length - 1].parts[0].text += '\n\n' + part.text;
|
||||||
}
|
}
|
||||||
if (part.inlineData) {
|
if (part.inlineData || part.functionCall || part.functionResponse) {
|
||||||
contents[contents.length - 1].parts.push(part);
|
contents[contents.length - 1].parts.push(part);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user