UNPKG

@lobehub/chat

Version:

Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.

95 lines (82 loc) 3.09 kB
import { responsesAPIModels } from '@/const/models'; import { ChatStreamPayload, ModelProvider } from '../types'; import { processMultiProviderModelList } from '../utils/modelParse'; import { createOpenAICompatibleRuntime } from '../utils/openaiCompatibleFactory'; import { pruneReasoningPayload } from '../utils/openaiHelpers'; export interface OpenAIModelCard { id: string; } const prunePrefixes = ['o1', 'o3', 'o4', 'codex', 'computer-use']; const oaiSearchContextSize = process.env.OPENAI_SEARCH_CONTEXT_SIZE; // low, medium, high export const LobeOpenAI = createOpenAICompatibleRuntime({ baseURL: 'https://api.openai.com/v1', chatCompletion: { handlePayload: (payload) => { const { enabledSearch, model, ...rest } = payload; if (responsesAPIModels.has(model) || enabledSearch) { return { ...rest, apiMode: 'responses', enabledSearch, model } as ChatStreamPayload; } if (prunePrefixes.some((prefix) => model.startsWith(prefix))) { return pruneReasoningPayload(payload) as any; } if (model.includes('-search-')) { return { ...rest, frequency_penalty: undefined, model, presence_penalty: undefined, stream: payload.stream ?? true, temperature: undefined, top_p: undefined, ...(oaiSearchContextSize && { web_search_options: { search_context_size: oaiSearchContextSize, }, }), } as any; } return { ...rest, model, stream: payload.stream ?? true }; }, }, debug: { chatCompletion: () => process.env.DEBUG_OPENAI_CHAT_COMPLETION === '1', responses: () => process.env.DEBUG_OPENAI_RESPONSES === '1', }, models: async ({ client }) => { const modelsPage = (await client.models.list()) as any; const modelList: OpenAIModelCard[] = modelsPage.data; // 自动检测模型提供商并选择相应配置 return processMultiProviderModelList(modelList); }, provider: ModelProvider.OpenAI, responses: { handlePayload: (payload) => { const { enabledSearch, model, tools, ...rest } = payload; const openaiTools = enabledSearch ? [ ...(tools || []), { type: 'web_search_preview', ...(oaiSearchContextSize && { search_context_size: oaiSearchContextSize, }), }, ] : tools; if (prunePrefixes.some((prefix) => model.startsWith(prefix))) { return pruneReasoningPayload({ ...rest, model, reasoning: payload.reasoning ? { ...payload.reasoning, summary: 'auto' } : { summary: 'auto' }, stream: payload.stream ?? true, tools: openaiTools as any, // computer-use series must set truncation as auto ...(model.startsWith('computer-use') && { truncation: 'auto' }), }) as any; } return { ...rest, model, stream: payload.stream ?? true, tools: openaiTools } as any; }, }, });