mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-24 18:50:56 +08:00
feat: update AI Core client types and provider registry
- Refactored `ApiClientFactory` and `UniversalAiSdkClient` to use the new `ProviderOptions` type for improved type safety. - Removed deprecated `AiCoreRequest` interface to streamline request handling. - Updated the provider registry to include the OpenRouter provider while removing unused providers, enhancing clarity and maintainability. - Added new dependencies and updated the pnpm-lock.yaml to reflect changes in provider versions.
This commit is contained in:
parent
7c1b7ee40f
commit
8910281b09
@ -69,8 +69,8 @@ importers:
|
||||
specifier: ^1.2.16
|
||||
version: 1.2.16(zod@3.25.67)
|
||||
'@openrouter/ai-sdk-provider':
|
||||
specifier: ^0.7.2
|
||||
version: 0.7.2(ai@4.3.16(react@19.1.0)(zod@3.25.67))(zod@3.25.67)
|
||||
specifier: ^0.1.0
|
||||
version: 0.1.0(zod@3.25.67)
|
||||
ai:
|
||||
specifier: ^4.3.16
|
||||
version: 4.3.16(react@19.1.0)(zod@3.25.67)
|
||||
@ -83,6 +83,9 @@ importers:
|
||||
qwen-ai-provider:
|
||||
specifier: ^0.1.0
|
||||
version: 0.1.0(zod@3.25.67)
|
||||
zhipu-ai-provider:
|
||||
specifier: ^0.1.1
|
||||
version: 0.1.1(zod@3.25.67)
|
||||
devDependencies:
|
||||
tsdown:
|
||||
specifier: ^0.12.8
|
||||
@ -198,6 +201,24 @@ packages:
|
||||
zod:
|
||||
optional: true
|
||||
|
||||
'@ai-sdk/provider-utils@2.1.10':
|
||||
resolution: {integrity: sha512-4GZ8GHjOFxePFzkl3q42AU0DQOtTQ5w09vmaWUf/pKFXJPizlnzKSUkF0f+VkapIUfDugyMqPMT1ge8XQzVI7Q==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
zod: ^3.0.0
|
||||
peerDependenciesMeta:
|
||||
zod:
|
||||
optional: true
|
||||
|
||||
'@ai-sdk/provider-utils@2.1.5':
|
||||
resolution: {integrity: sha512-PcNR7E4ovZGV/J47gUqaFlvzorgca6uUfN5WzfXJSFWeOeLunN+oxRVwgUOwj0zbmO0yGQTHQD+FHVw8s3Rz8w==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
zod: ^3.0.0
|
||||
peerDependenciesMeta:
|
||||
zod:
|
||||
optional: true
|
||||
|
||||
'@ai-sdk/provider-utils@2.2.8':
|
||||
resolution: {integrity: sha512-fqhG+4sCVv8x7nFzYnFo19ryhAa3w096Kmc3hWxMQfW/TubPOmt3A6tYZhl4mUfQWWQMsuSkLrtjlWuXBVSGQA==}
|
||||
engines: {node: '>=18'}
|
||||
@ -208,6 +229,14 @@ packages:
|
||||
resolution: {integrity: sha512-XMsNGJdGO+L0cxhhegtqZ8+T6nn4EoShS819OvCgI2kLbYTIvk0GWFGD0AXJmxkxs3DrpsJxKAFukFR7bvTkgQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@ai-sdk/provider@1.0.6':
|
||||
resolution: {integrity: sha512-hwj/gFNxpDgEfTaYzCYoslmw01IY9kWLKl/wf8xuPvHtQIzlfXWmmUwc8PnCwxyt8cKzIuV0dfUghCf68HQ0SA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@ai-sdk/provider@1.0.9':
|
||||
resolution: {integrity: sha512-jie6ZJT2ZR0uVOVCDc9R2xCX5I/Dum/wEK28lx21PJx6ZnFAN9EzD2WsPhcDWfCgGx3OAZZ0GyM3CEobXpa9LA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@ai-sdk/provider@1.1.3':
|
||||
resolution: {integrity: sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg==}
|
||||
engines: {node: '>=18'}
|
||||
@ -314,12 +343,11 @@ packages:
|
||||
'@napi-rs/wasm-runtime@0.2.11':
|
||||
resolution: {integrity: sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==}
|
||||
|
||||
'@openrouter/ai-sdk-provider@0.7.2':
|
||||
resolution: {integrity: sha512-Fry2mV7uGGJRmP9JntTZRc8ElESIk7AJNTacLbF6Syoeb5k8d7HPGkcK9rTXDlqBb8HgU1hOKtz23HojesTmnw==}
|
||||
'@openrouter/ai-sdk-provider@0.1.0':
|
||||
resolution: {integrity: sha512-kETuMSFu31Z9ND1lEl8cmXy+csCZBopKEpe33Pxz/B6J/AYOlGxvmdPKWlMqwkvE1dISuPMh9IL97Q6dof2Liw==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
ai: ^4.3.16
|
||||
zod: ^3.25.34
|
||||
zod: ^3.0.0
|
||||
|
||||
'@opentelemetry/api@1.9.0':
|
||||
resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
|
||||
@ -539,6 +567,10 @@ packages:
|
||||
resolution: {integrity: sha512-v0eOBUbiaFojBu2s2NPBfYUoRR9GjcDNvCXVaqEf5vVfpIAh9f8RCo4vXTP8c63QRKCFwoLpMpTdPwwhEKVgzA==}
|
||||
engines: {node: '>=14.18'}
|
||||
|
||||
eventsource-parser@3.0.2:
|
||||
resolution: {integrity: sha512-6RxOBZ/cYgd8usLwsEl+EC09Au/9BcmCKYF2/xbml6DNczf7nv0MQb+7BA2F+li6//I+28VNlQR37XfQtcAJuA==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
extend@3.0.2:
|
||||
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
|
||||
|
||||
@ -769,6 +801,12 @@ packages:
|
||||
whatwg-url@5.0.0:
|
||||
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||
|
||||
zhipu-ai-provider@0.1.1:
|
||||
resolution: {integrity: sha512-cVwvvGtPiQqgsGdBzHCHC5oQ7z6slEQTbXJ5+42gQGX4N5uRUvYj+YYLp7Cr1HPQGF3zR2p8vNbT5etPHD4NbA==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
zod: ^3.0.0
|
||||
|
||||
zod-to-json-schema@3.24.5:
|
||||
resolution: {integrity: sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==}
|
||||
peerDependencies:
|
||||
@ -898,6 +936,24 @@ snapshots:
|
||||
optionalDependencies:
|
||||
zod: 3.25.67
|
||||
|
||||
'@ai-sdk/provider-utils@2.1.10(zod@3.25.67)':
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 1.0.9
|
||||
eventsource-parser: 3.0.2
|
||||
nanoid: 3.3.11
|
||||
secure-json-parse: 2.7.0
|
||||
optionalDependencies:
|
||||
zod: 3.25.67
|
||||
|
||||
'@ai-sdk/provider-utils@2.1.5(zod@3.25.67)':
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 1.0.6
|
||||
eventsource-parser: 3.0.2
|
||||
nanoid: 3.3.11
|
||||
secure-json-parse: 2.7.0
|
||||
optionalDependencies:
|
||||
zod: 3.25.67
|
||||
|
||||
'@ai-sdk/provider-utils@2.2.8(zod@3.25.67)':
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 1.1.3
|
||||
@ -909,6 +965,14 @@ snapshots:
|
||||
dependencies:
|
||||
json-schema: 0.4.0
|
||||
|
||||
'@ai-sdk/provider@1.0.6':
|
||||
dependencies:
|
||||
json-schema: 0.4.0
|
||||
|
||||
'@ai-sdk/provider@1.0.9':
|
||||
dependencies:
|
||||
json-schema: 0.4.0
|
||||
|
||||
'@ai-sdk/provider@1.1.3':
|
||||
dependencies:
|
||||
json-schema: 0.4.0
|
||||
@ -1035,11 +1099,10 @@ snapshots:
|
||||
'@tybys/wasm-util': 0.9.0
|
||||
optional: true
|
||||
|
||||
'@openrouter/ai-sdk-provider@0.7.2(ai@4.3.16(react@19.1.0)(zod@3.25.67))(zod@3.25.67)':
|
||||
'@openrouter/ai-sdk-provider@0.1.0(zod@3.25.67)':
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 1.1.3
|
||||
'@ai-sdk/provider-utils': 2.2.8(zod@3.25.67)
|
||||
ai: 4.3.16(react@19.1.0)(zod@3.25.67)
|
||||
'@ai-sdk/provider': 1.0.6
|
||||
'@ai-sdk/provider-utils': 2.1.5(zod@3.25.67)
|
||||
zod: 3.25.67
|
||||
|
||||
'@opentelemetry/api@1.9.0': {}
|
||||
@ -1213,6 +1276,8 @@ snapshots:
|
||||
|
||||
eventsource-parser@1.1.2: {}
|
||||
|
||||
eventsource-parser@3.0.2: {}
|
||||
|
||||
extend@3.0.2: {}
|
||||
|
||||
fdir@6.4.6(picomatch@4.0.2):
|
||||
@ -1448,6 +1513,12 @@ snapshots:
|
||||
tr46: 0.0.3
|
||||
webidl-conversions: 3.0.1
|
||||
|
||||
zhipu-ai-provider@0.1.1(zod@3.25.67):
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 1.0.9
|
||||
'@ai-sdk/provider-utils': 2.1.10(zod@3.25.67)
|
||||
zod: 3.25.67
|
||||
|
||||
zod-to-json-schema@3.24.5(zod@3.25.67):
|
||||
dependencies:
|
||||
zod: 3.25.67
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
import type { LanguageModelV1 } from 'ai'
|
||||
|
||||
import { aiProviderRegistry } from '../providers/registry'
|
||||
import { ProviderOptions } from './types'
|
||||
|
||||
// 客户端配置接口
|
||||
export interface ClientConfig {
|
||||
@ -37,7 +38,7 @@ export class ApiClientFactory {
|
||||
static async createClient(
|
||||
providerId: string,
|
||||
modelId: string = 'default',
|
||||
options: any = {}
|
||||
options: ProviderOptions
|
||||
): Promise<LanguageModelV1> {
|
||||
try {
|
||||
// 验证provider是否支持
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
import { generateObject, generateText, streamObject, streamText } from 'ai'
|
||||
|
||||
import { ApiClientFactory } from './ApiClientFactory'
|
||||
import { ProviderOptions } from './types'
|
||||
|
||||
/**
|
||||
* 通用 AI SDK 客户端
|
||||
@ -14,16 +15,19 @@ import { ApiClientFactory } from './ApiClientFactory'
|
||||
export class UniversalAiSdkClient {
|
||||
constructor(
|
||||
private readonly providerId: string,
|
||||
private readonly options: any = {}
|
||||
private readonly options: ProviderOptions
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 流式文本生成
|
||||
* 直接使用 AI SDK 的 streamText 参数类型
|
||||
*/
|
||||
async streamText(modelId: string, params: Omit<Parameters<typeof streamText>[0], 'model'>) {
|
||||
async streamText(
|
||||
modelId: string,
|
||||
params: Omit<Parameters<typeof streamText>[0], 'model'>
|
||||
): Promise<ReturnType<typeof streamText>> {
|
||||
const model = await ApiClientFactory.createClient(this.providerId, modelId, this.options)
|
||||
return await streamText({
|
||||
return streamText({
|
||||
model,
|
||||
...params
|
||||
})
|
||||
@ -33,9 +37,12 @@ export class UniversalAiSdkClient {
|
||||
* 生成文本
|
||||
* 直接使用 AI SDK 的 generateText 参数类型
|
||||
*/
|
||||
async generateText(modelId: string, params: Omit<Parameters<typeof generateText>[0], 'model'>) {
|
||||
async generateText(
|
||||
modelId: string,
|
||||
params: Omit<Parameters<typeof generateText>[0], 'model'>
|
||||
): Promise<ReturnType<typeof generateText>> {
|
||||
const model = await ApiClientFactory.createClient(this.providerId, modelId, this.options)
|
||||
return await generateText({
|
||||
return generateText({
|
||||
model,
|
||||
...params
|
||||
})
|
||||
@ -45,7 +52,10 @@ export class UniversalAiSdkClient {
|
||||
* 生成结构化对象
|
||||
* 直接使用 AI SDK 的 generateObject 参数类型
|
||||
*/
|
||||
async generateObject(modelId: string, params: Omit<Parameters<typeof generateObject>[0], 'model'>) {
|
||||
async generateObject(
|
||||
modelId: string,
|
||||
params: Omit<Parameters<typeof generateObject>[0], 'model'>
|
||||
): Promise<ReturnType<typeof generateObject>> {
|
||||
const model = await ApiClientFactory.createClient(this.providerId, modelId, this.options)
|
||||
return await generateObject({
|
||||
model,
|
||||
@ -57,9 +67,12 @@ export class UniversalAiSdkClient {
|
||||
* 流式生成结构化对象
|
||||
* 直接使用 AI SDK 的 streamObject 参数类型
|
||||
*/
|
||||
async streamObject(modelId: string, params: Omit<Parameters<typeof streamObject>[0], 'model'>) {
|
||||
async streamObject(
|
||||
modelId: string,
|
||||
params: Omit<Parameters<typeof streamObject>[0], 'model'>
|
||||
): Promise<ReturnType<typeof streamObject>> {
|
||||
const model = await ApiClientFactory.createClient(this.providerId, modelId, this.options)
|
||||
return await streamObject({
|
||||
return streamObject({
|
||||
model,
|
||||
...params
|
||||
})
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
import { CoreMessage } from 'ai'
|
||||
|
||||
export type ProviderOptions = {
|
||||
name: string
|
||||
apiKey?: string
|
||||
@ -7,17 +5,3 @@ export type ProviderOptions = {
|
||||
apiVersion?: string
|
||||
headers?: Record<string, string | unknown>
|
||||
}
|
||||
|
||||
export interface AiCoreRequest {
|
||||
modelId: string
|
||||
messages: CoreMessage[]
|
||||
tools?: Record<string, any>
|
||||
maxTokens?: number
|
||||
temperature?: number
|
||||
topP?: number
|
||||
frequencyPenalty?: number
|
||||
presencePenalty?: number
|
||||
maxRetries?: number
|
||||
abortSignal?: AbortSignal
|
||||
headers?: Record<string, string | undefined>
|
||||
}
|
||||
|
||||
@ -158,30 +158,6 @@ export class AiProviderRegistry {
|
||||
name: 'Vercel',
|
||||
import: () => import('@ai-sdk/vercel'),
|
||||
creatorFunctionName: 'createVercel'
|
||||
},
|
||||
{
|
||||
id: 'qwen',
|
||||
name: 'Qwen',
|
||||
import: () => import('qwen-ai-provider'),
|
||||
creatorFunctionName: 'createQwen'
|
||||
},
|
||||
{
|
||||
id: 'ollama',
|
||||
name: 'Ollama',
|
||||
import: () => import('ollama-ai-provider'),
|
||||
creatorFunctionName: 'createOllama'
|
||||
},
|
||||
{
|
||||
id: 'anthropic-vertex',
|
||||
name: 'Anthropic Vertex',
|
||||
import: () => import('anthropic-vertex-ai'),
|
||||
creatorFunctionName: 'createAnthropicVertex'
|
||||
},
|
||||
{
|
||||
id: 'openrouter',
|
||||
name: 'OpenRouter',
|
||||
import: () => import('@openrouter/ai-sdk-provider'),
|
||||
creatorFunctionName: 'createOpenRouter'
|
||||
}
|
||||
]
|
||||
|
||||
@ -210,6 +186,12 @@ export class AiProviderRegistry {
|
||||
name: 'Anthropic Vertex AI',
|
||||
import: () => import('anthropic-vertex-ai'),
|
||||
creatorFunctionName: 'createAnthropicVertex'
|
||||
},
|
||||
{
|
||||
id: 'openrouter',
|
||||
name: 'OpenRouter',
|
||||
import: () => import('@openrouter/ai-sdk-provider'),
|
||||
creatorFunctionName: 'createOpenRouter'
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user