| import { EModelEndpoint } from 'librechat-data-provider'; |
| import type { GoogleAIToolType } from '@langchain/google-common'; |
| import type { ClientOptions } from '@librechat/agents'; |
| import type * as t from '~/types'; |
| import { knownOpenAIParams } from './llm'; |
|
|
| const anthropicExcludeParams = new Set(['anthropicApiUrl']); |
| const googleExcludeParams = new Set([ |
| 'safetySettings', |
| 'location', |
| 'baseUrl', |
| 'customHeaders', |
| 'thinkingConfig', |
| 'thinkingBudget', |
| 'includeThoughts', |
| ]); |
|
|
| |
| const googleToolsToFilter = new Set(['googleSearch']); |
|
|
| export type ConfigTools = Array<Record<string, unknown>> | Array<GoogleAIToolType>; |
|
|
| |
| |
| |
| |
| |
| |
| |
| export function transformToOpenAIConfig({ |
| tools, |
| addParams, |
| dropParams, |
| defaultParams, |
| llmConfig, |
| fromEndpoint, |
| }: { |
| tools?: ConfigTools; |
| addParams?: Record<string, unknown>; |
| dropParams?: string[]; |
| defaultParams?: Record<string, unknown>; |
| llmConfig: ClientOptions; |
| fromEndpoint: string; |
| }): { |
| tools: ConfigTools; |
| llmConfig: t.OAIClientOptions; |
| configOptions: Partial<t.OpenAIConfiguration>; |
| } { |
| const openAIConfig: Partial<t.OAIClientOptions> = {}; |
| let configOptions: Partial<t.OpenAIConfiguration> = {}; |
| let modelKwargs: Record<string, unknown> = {}; |
| let hasModelKwargs = false; |
|
|
| const isAnthropic = fromEndpoint === EModelEndpoint.anthropic; |
| const isGoogle = fromEndpoint === EModelEndpoint.google; |
|
|
| let excludeParams = new Set<string>(); |
| if (isAnthropic) { |
| excludeParams = anthropicExcludeParams; |
| } else if (isGoogle) { |
| excludeParams = googleExcludeParams; |
| } |
|
|
| for (const [key, value] of Object.entries(llmConfig)) { |
| if (value === undefined || value === null) { |
| continue; |
| } |
|
|
| if (excludeParams.has(key)) { |
| continue; |
| } |
|
|
| if (isAnthropic && key === 'clientOptions') { |
| configOptions = Object.assign({}, configOptions, value as Partial<t.OpenAIConfiguration>); |
| continue; |
| } else if (isAnthropic && key === 'invocationKwargs') { |
| modelKwargs = Object.assign({}, modelKwargs, value as Record<string, unknown>); |
| hasModelKwargs = true; |
| continue; |
| } else if (isGoogle && key === 'authOptions') { |
| modelKwargs = Object.assign({}, modelKwargs, value as Record<string, unknown>); |
| hasModelKwargs = true; |
| continue; |
| } |
|
|
| if (knownOpenAIParams.has(key)) { |
| (openAIConfig as Record<string, unknown>)[key] = value; |
| } else { |
| modelKwargs[key] = value; |
| hasModelKwargs = true; |
| } |
| } |
|
|
| if (addParams && typeof addParams === 'object') { |
| for (const [key, value] of Object.entries(addParams)) { |
| |
| if (key === 'web_search') { |
| continue; |
| } |
|
|
| if (knownOpenAIParams.has(key)) { |
| (openAIConfig as Record<string, unknown>)[key] = value; |
| } else { |
| modelKwargs[key] = value; |
| hasModelKwargs = true; |
| } |
| } |
| } |
|
|
| if (hasModelKwargs) { |
| openAIConfig.modelKwargs = modelKwargs; |
| } |
|
|
| if (dropParams && Array.isArray(dropParams)) { |
| dropParams.forEach((param) => { |
| |
| if (param === 'web_search') { |
| return; |
| } |
|
|
| if (param in openAIConfig) { |
| delete openAIConfig[param as keyof t.OAIClientOptions]; |
| } |
| if (openAIConfig.modelKwargs && param in openAIConfig.modelKwargs) { |
| delete openAIConfig.modelKwargs[param]; |
| } |
| }); |
|
|
| |
| if (openAIConfig.modelKwargs && Object.keys(openAIConfig.modelKwargs).length === 0) { |
| delete openAIConfig.modelKwargs; |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| const webSearchExplicitlyEnabled = |
| addParams?.web_search === true || defaultParams?.web_search === true; |
|
|
| const filterGoogleTool = (tool: unknown): boolean => { |
| if (!isGoogle) { |
| return true; |
| } |
| if (typeof tool !== 'object' || tool === null) { |
| return false; |
| } |
| const toolKeys = Object.keys(tool as Record<string, unknown>); |
| const isGoogleSpecificTool = toolKeys.some((key) => googleToolsToFilter.has(key)); |
| |
| if (isGoogleSpecificTool && webSearchExplicitlyEnabled) { |
| return true; |
| } |
| return !isGoogleSpecificTool; |
| }; |
|
|
| const filteredTools = Array.isArray(tools) ? tools.filter(filterGoogleTool) : []; |
|
|
| return { |
| tools: filteredTools, |
| llmConfig: openAIConfig as t.OAIClientOptions, |
| configOptions, |
| }; |
| } |
|
|