diff --git a/packages/aiCore/src/core/models/ProviderCreator.ts b/packages/aiCore/src/core/models/ProviderCreator.ts index 811c5388e9..8382220e5a 100644 --- a/packages/aiCore/src/core/models/ProviderCreator.ts +++ b/packages/aiCore/src/core/models/ProviderCreator.ts @@ -33,7 +33,7 @@ export async function createBaseModel({ }: { providerId: T modelId: string - providerSettings: ProviderSettingsMap[T] + providerSettings: ProviderSettingsMap[T] & { mode?: 'chat' | 'responses' } extraModelConfig?: any // middlewares?: LanguageModelV1Middleware[] }): Promise @@ -47,7 +47,7 @@ export async function createBaseModel({ }: { providerId: string modelId: string - providerSettings: ProviderSettingsMap['openai-compatible'] + providerSettings: ProviderSettingsMap['openai-compatible'] & { mode?: 'chat' | 'responses' } extraModelConfig?: any // middlewares?: LanguageModelV1Middleware[] }): Promise @@ -61,7 +61,7 @@ export async function createBaseModel({ }: { providerId: string modelId: string - providerSettings: ProviderSettingsMap[ProviderId] + providerSettings: ProviderSettingsMap[ProviderId] & { mode?: 'chat' | 'responses' } // middlewares?: LanguageModelV1Middleware[] extraModelConfig?: any }): Promise { @@ -86,6 +86,7 @@ export async function createBaseModel({ `Creator function "${providerConfig.creatorFunctionName}" not found in the imported module for provider "${effectiveProviderId}"` ) } + // TODO: 对openai 的 providerSettings.mode参数是否要删除,目前看没毛病 // 创建provider实例 let provider = creatorFunction(providerSettings) @@ -93,7 +94,7 @@ export async function createBaseModel({ if (providerConfig.id === 'openai') { if ( 'mode' in providerSettings && - providerSettings.mode === 'response' && + providerSettings.mode === 'responses' && !isOpenAIChatCompletionOnlyModel(modelId) ) { provider = provider.responses diff --git a/packages/aiCore/src/core/models/types.ts b/packages/aiCore/src/core/models/types.ts index c29e459557..eb4844125d 100644 --- a/packages/aiCore/src/core/models/types.ts +++ b/packages/aiCore/src/core/models/types.ts @@ -8,7 +8,7 @@ import type { ProviderId, ProviderSettingsMap } from '../../types' export interface ModelConfig { providerId: T modelId: string - providerSettings: ProviderSettingsMap[T] & { mode: 'chat' | 'responses' } + providerSettings: ProviderSettingsMap[T] & { mode?: 'chat' | 'responses' } middlewares?: LanguageModelV2Middleware[] // 额外模型参数 extraModelConfig?: Record diff --git a/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/helper.ts b/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/helper.ts index d5f9b682c2..8d7cba4a5f 100644 --- a/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/helper.ts +++ b/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/helper.ts @@ -1,4 +1,5 @@ import { anthropic } from '@ai-sdk/anthropic' +import { google } from '@ai-sdk/google' import { openai } from '@ai-sdk/openai' import { ProviderOptionsMap } from '../../../options/types' @@ -8,16 +9,7 @@ import { ProviderOptionsMap } from '../../../options/types' */ type OpenAISearchConfig = Parameters[0] type AnthropicSearchConfig = Parameters[0] -/** - * XAI 特有的搜索参数 - * @internal - */ -interface XaiProviderOptions { - searchParameters?: { - sources?: any[] - safeSearch?: boolean - } -} +type GoogleSearchConfig = Parameters[0] /** * 插件初始化时接收的完整配置对象 @@ -28,20 +20,16 @@ export interface WebSearchPluginConfig { openai?: OpenAISearchConfig anthropic?: AnthropicSearchConfig xai?: ProviderOptionsMap['xai']['searchParameters'] - google?: Pick - 'google-vertex'?: Pick + google?: GoogleSearchConfig + 'google-vertex'?: GoogleSearchConfig } /** * 插件的默认配置 */ export const DEFAULT_WEB_SEARCH_CONFIG: WebSearchPluginConfig = { - google: { - useSearchGrounding: true - }, - 'google-vertex': { - useSearchGrounding: true - }, + google: {}, + 'google-vertex': {}, openai: {}, xai: { mode: 'on', @@ -53,37 +41,3 @@ export const DEFAULT_WEB_SEARCH_CONFIG: WebSearchPluginConfig = { maxUses: 5 } } - -/** - * 根据配置构建 Google 的 providerOptions - */ -export const getGoogleProviderOptions = (providerOptions: any) => { - if (!providerOptions) providerOptions = {} - if (!providerOptions.google) providerOptions.google = {} - providerOptions.google.useSearchGrounding = true - return providerOptions -} - -/** - * 根据配置构建 XAI 的 providerOptions - */ -export const getXaiProviderOptions = (providerOptions: any, config?: XaiProviderOptions['searchParameters']) => { - if (!providerOptions) providerOptions = {} - if (!providerOptions.xai) providerOptions.xai = {} - providerOptions.xai.searchParameters = { - mode: 'on', - ...(config ?? {}) - } - return providerOptions -} - -export type AnthropicSearchInput = { - query: string -} -export type AnthropicSearchOutput = { - url: string - title: string - pageAge: string | null - encryptedContent: string - type: string -}[] diff --git a/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/index.ts b/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/index.ts index 5daeff8699..811d06c9c3 100644 --- a/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/index.ts +++ b/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/index.ts @@ -3,9 +3,10 @@ * 提供统一的网络搜索能力,支持多个 AI Provider */ import { anthropic } from '@ai-sdk/anthropic' +import { google } from '@ai-sdk/google' import { openai } from '@ai-sdk/openai' -import { createGoogleOptions, createXaiOptions, mergeProviderOptions } from '../../../options' +import { createXaiOptions, mergeProviderOptions } from '../../../options' import { definePlugin } from '../../' import type { AiRequestContext } from '../../types' import { DEFAULT_WEB_SEARCH_CONFIG, WebSearchPluginConfig } from './helper' @@ -22,15 +23,12 @@ export const webSearchPlugin = (config: WebSearchPluginConfig = DEFAULT_WEB_SEAR transformParams: async (params: any, context: AiRequestContext) => { const { providerId } = context - // console.log('providerId', providerId) - // const modelToProviderId = getModelToProviderId(modelId) - // console.log('modelToProviderId', modelToProviderId) + console.log('providerId', providerId) switch (providerId) { case 'openai': { if (config.openai) { if (!params.tools) params.tools = {} params.tools.web_search_preview = openai.tools.webSearchPreview(config.openai) - // console.log('params.tools', params.tools) } break } @@ -45,11 +43,8 @@ export const webSearchPlugin = (config: WebSearchPluginConfig = DEFAULT_WEB_SEAR case 'google': case 'google-vertex': { - // @ts-ignore - providerId is a string that can be used to index config - if (config[providerId]) { - const searchOptions = createGoogleOptions({ useSearchGrounding: true }) - params.providerOptions = mergeProviderOptions(params.providerOptions, searchOptions) - } + if (!params.tools) params.tools = {} + params.tools.web_search = google.tools.googleSearch(config.google || {}) break } @@ -62,23 +57,14 @@ export const webSearchPlugin = (config: WebSearchPluginConfig = DEFAULT_WEB_SEAR } break } - // default: { - // if (!params.providerOptions) params.providerOptions = {} - // params.providerOptions['aihubmix'] = { - // web_search: anthropic.tools.webSearch_20250305() - // } - // console.log('params.providerOptions', params.providerOptions) - // break - // } } - // console.log('params', params) return params } }) // 导出类型定义供开发者使用 -export type { AnthropicSearchInput, AnthropicSearchOutput, WebSearchPluginConfig } from './helper' +export type { WebSearchPluginConfig } from './helper' // 默认导出 export default webSearchPlugin diff --git a/packages/aiCore/src/core/runtime/index.ts b/packages/aiCore/src/core/runtime/index.ts index e6a03a4340..09e875f11b 100644 --- a/packages/aiCore/src/core/runtime/index.ts +++ b/packages/aiCore/src/core/runtime/index.ts @@ -27,7 +27,7 @@ import { RuntimeExecutor } from './executor' */ export function createExecutor( providerId: T, - options: ProviderSettingsMap[T], + options: ProviderSettingsMap[T] & { mode?: 'chat' | 'responses' }, plugins?: AiPlugin[] ): RuntimeExecutor { return RuntimeExecutor.create(providerId, options, plugins) @@ -37,7 +37,7 @@ export function createExecutor( * 创建OpenAI Compatible执行器 */ export function createOpenAICompatibleExecutor( - options: ProviderSettingsMap['openai-compatible'], + options: ProviderSettingsMap['openai-compatible'] & { mode?: 'chat' | 'responses' }, plugins: AiPlugin[] = [] ): RuntimeExecutor<'openai-compatible'> { return RuntimeExecutor.createOpenAICompatible(options, plugins) @@ -50,7 +50,7 @@ export function createOpenAICompatibleExecutor( */ export async function streamText( providerId: T, - options: ProviderSettingsMap[T], + options: ProviderSettingsMap[T] & { mode?: 'chat' | 'responses' }, modelId: string, params: Parameters['streamText']>[1], plugins?: AiPlugin[], @@ -65,7 +65,7 @@ export async function streamText( */ export async function generateText( providerId: T, - options: ProviderSettingsMap[T], + options: ProviderSettingsMap[T] & { mode?: 'chat' | 'responses' }, modelId: string, params: Parameters['generateText']>[1], plugins?: AiPlugin[], @@ -80,7 +80,7 @@ export async function generateText( */ export async function generateObject( providerId: T, - options: ProviderSettingsMap[T], + options: ProviderSettingsMap[T] & { mode?: 'chat' | 'responses' }, modelId: string, params: Parameters['generateObject']>[1], plugins?: AiPlugin[], @@ -95,7 +95,7 @@ export async function generateObject( */ export async function streamObject( providerId: T, - options: ProviderSettingsMap[T], + options: ProviderSettingsMap[T] & { mode?: 'chat' | 'responses' }, modelId: string, params: Parameters['streamObject']>[1], plugins?: AiPlugin[], diff --git a/packages/aiCore/src/core/runtime/types.ts b/packages/aiCore/src/core/runtime/types.ts index 83bdd9ecdd..3f49ea8d77 100644 --- a/packages/aiCore/src/core/runtime/types.ts +++ b/packages/aiCore/src/core/runtime/types.ts @@ -10,7 +10,7 @@ import { type AiPlugin } from '../plugins' */ export interface RuntimeConfig { providerId: T - providerSettings: ModelConfig['providerSettings'] + providerSettings: ModelConfig['providerSettings'] & { mode?: 'chat' | 'responses' } plugins?: AiPlugin[] } diff --git a/src/renderer/src/aiCore/chunk/AiSdkToChunkAdapter.ts b/src/renderer/src/aiCore/chunk/AiSdkToChunkAdapter.ts index 35168ccf3f..0b9518a40c 100644 --- a/src/renderer/src/aiCore/chunk/AiSdkToChunkAdapter.ts +++ b/src/renderer/src/aiCore/chunk/AiSdkToChunkAdapter.ts @@ -133,11 +133,11 @@ export class AiSdkToChunkAdapter { // === 工具调用相关事件(原始 AI SDK 事件,如果没有被中间件处理) === - case 'tool-input-start': - case 'tool-input-delta': - case 'tool-input-end': - this.toolCallHandler.handleToolCallCreated(chunk) - break + // case 'tool-input-start': + // case 'tool-input-delta': + // case 'tool-input-end': + // this.toolCallHandler.handleToolCallCreated(chunk) + // break // case 'tool-input-delta': // this.toolCallHandler.handleToolCallCreated(chunk) diff --git a/src/renderer/src/aiCore/index_new.ts b/src/renderer/src/aiCore/index_new.ts index 24ddab0b55..8c75e571a2 100644 --- a/src/renderer/src/aiCore/index_new.ts +++ b/src/renderer/src/aiCore/index_new.ts @@ -46,7 +46,6 @@ function getActualProvider(model: Model): Provider { if (provider.id === 'aihubmix') { actualProvider = createAihubmixProvider(model, actualProvider) - console.log('actualProvider', actualProvider) } if (actualProvider.type === 'gemini') { actualProvider.apiHost = formatApiHost(actualProvider.apiHost, 'v1beta') @@ -67,13 +66,14 @@ function providerToAiSdkConfig(actualProvider: Provider): { const aiSdkProviderId = getAiSdkProviderId(actualProvider) // console.log('aiSdkProviderId', aiSdkProviderId) // 如果provider是openai,则使用strict模式并且默认responses api - const actualProviderType = actualProvider.type + const actualProviderId = actualProvider.id const openaiResponseOptions = - actualProviderType === 'openai-response' + // 对于实际是openai的需要走responses,aiCore内部会判断model是否可用responses + actualProviderId === 'openai' ? { - mode: 'response' + mode: 'responses' } - : actualProviderType === 'openai' + : aiSdkProviderId === 'openai' ? { mode: 'chat' } @@ -86,10 +86,9 @@ function providerToAiSdkConfig(actualProvider: Provider): { aiSdkProviderId, { baseURL: actualProvider.apiHost, - apiKey: actualProvider.apiKey, - headers: actualProvider.extra_headers + apiKey: actualProvider.apiKey }, - openaiResponseOptions + { ...openaiResponseOptions, headers: actualProvider.extra_headers } ) return { @@ -224,7 +223,9 @@ export default class ModernAiProvider { // try { // 根据条件构建插件数组 const plugins = this.buildPlugins(middlewareConfig) - + console.log('this.config.providerId', this.config.providerId) + console.log('this.config.options', this.config.options) + console.log('plugins', plugins) // 用构建好的插件数组创建executor const executor = createExecutor(this.config.providerId, this.config.options, plugins) diff --git a/src/renderer/src/aiCore/provider/factory.ts b/src/renderer/src/aiCore/provider/factory.ts index d7edb92b73..2711df003f 100644 --- a/src/renderer/src/aiCore/provider/factory.ts +++ b/src/renderer/src/aiCore/provider/factory.ts @@ -26,6 +26,9 @@ export function getAiSdkProviderId(provider: Provider): ProviderId | 'openai-com if (AiCore.isSupported(provider.id)) { return provider.id as ProviderId } + if (AiCore.isSupported(provider.type)) { + return provider.type as ProviderId + } return provider.id as ProviderId } diff --git a/src/renderer/src/aiCore/utils/options.ts b/src/renderer/src/aiCore/utils/options.ts index 00e6385d9e..7aa8ea1fed 100644 --- a/src/renderer/src/aiCore/utils/options.ts +++ b/src/renderer/src/aiCore/utils/options.ts @@ -35,7 +35,12 @@ export function buildProviderOptions( switch (providerId) { case 'openai': case 'azure': - providerSpecificOptions = buildOpenAIProviderOptions(assistant, model, capabilities) + providerSpecificOptions = { + ...buildOpenAIProviderOptions(assistant, model, capabilities), + // 函数内有对于真实provider.id的判断,应该不会影响原生provider + ...buildGenericProviderOptions(assistant, model, capabilities) + } + break case 'anthropic':