mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-10 15:49:29 +08:00
feat: define types for AI core requests and provider options
feat: define types for AI core requests and provider options - Introduced `ProviderOptions` type to standardize provider configuration. - Added `AiCoreRequest` interface to encapsulate request parameters for AI operations. - Updated `UniversalAiSdkClient` to utilize the new types, enhancing type safety and clarity in API interactions. feat: update AI provider registry and dependencies - Added new AI providers: OpenAI Compatible, Qwen, Ollama, and Anthropic Vertex to the provider registry. - Updated package.json to include new dependencies for the added providers. - Enhanced pnpm-lock.yaml with corresponding versions and peer dependencies for the new packages.
This commit is contained in:
parent
7187e63ce2
commit
b771873f6c
@ -5,7 +5,7 @@
|
|||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsdown",
|
||||||
"dev": "tsc -w",
|
"dev": "tsc -w",
|
||||||
"clean": "rm -rf dist"
|
"clean": "rm -rf dist"
|
||||||
},
|
},
|
||||||
@ -35,12 +35,17 @@
|
|||||||
"@ai-sdk/groq": "^1.2.9",
|
"@ai-sdk/groq": "^1.2.9",
|
||||||
"@ai-sdk/mistral": "^1.2.8",
|
"@ai-sdk/mistral": "^1.2.8",
|
||||||
"@ai-sdk/openai": "^1.3.22",
|
"@ai-sdk/openai": "^1.3.22",
|
||||||
|
"@ai-sdk/openai-compatible": "^0.2.14",
|
||||||
"@ai-sdk/perplexity": "^1.1.9",
|
"@ai-sdk/perplexity": "^1.1.9",
|
||||||
"@ai-sdk/replicate": "^0.2.8",
|
"@ai-sdk/replicate": "^0.2.8",
|
||||||
"@ai-sdk/togetherai": "^0.2.14",
|
"@ai-sdk/togetherai": "^0.2.14",
|
||||||
"@ai-sdk/vercel": "^0.0.1",
|
"@ai-sdk/vercel": "^0.0.1",
|
||||||
"@ai-sdk/xai": "^1.2.16",
|
"@ai-sdk/xai": "^1.2.16",
|
||||||
"ai": "^4.3.16"
|
"@openrouter/ai-sdk-provider": "^0.7.2",
|
||||||
|
"ai": "^4.3.16",
|
||||||
|
"anthropic-vertex-ai": "^1.0.2",
|
||||||
|
"ollama-ai-provider": "^1.2.0",
|
||||||
|
"qwen-ai-provider": "^0.1.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"@ai-sdk/amazon-bedrock": {
|
"@ai-sdk/amazon-bedrock": {
|
||||||
@ -102,6 +107,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"tsdown": "^0.12.8",
|
||||||
"typescript": "^5.0.0"
|
"typescript": "^5.0.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
@ -113,5 +119,6 @@
|
|||||||
"import": "./dist/index.js",
|
"import": "./dist/index.js",
|
||||||
"require": "./dist/index.js"
|
"require": "./dist/index.js"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"packageManager": "pnpm"
|
||||||
}
|
}
|
||||||
|
|||||||
1455
packages/aiCore/pnpm-lock.yaml
Normal file
1455
packages/aiCore/pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load Diff
@ -3,9 +3,10 @@
|
|||||||
* 基于现有实现的简化版统一AI SDK客户端
|
* 基于现有实现的简化版统一AI SDK客户端
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { generateText, streamText } from 'ai'
|
import { CoreMessage, generateText, GenerateTextResult, streamText, StreamTextResult } from 'ai'
|
||||||
|
|
||||||
import { aiProviderRegistry } from '../providers/registry'
|
import { aiProviderRegistry } from '../providers/registry'
|
||||||
|
import { AiCoreRequest, ProviderOptions } from './types'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Universal AI SDK Client
|
* Universal AI SDK Client
|
||||||
@ -18,7 +19,7 @@ export class UniversalAiSdkClient {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private providerName: string,
|
private providerName: string,
|
||||||
private options: any // API keys, etc.
|
private options: ProviderOptions
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,7 +43,7 @@ export class UniversalAiSdkClient {
|
|||||||
|
|
||||||
if (typeof creatorFunction !== 'function') {
|
if (typeof creatorFunction !== 'function') {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Creator function "${this.providerConfig.creatorFunctionName}" not found in the imported module for provider "${this.providerName}".`
|
`Creator function "${this.providerConfig.creatorFunctionName}" not found in the imported module for provider "${this.options.name}".`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,13 +76,13 @@ export class UniversalAiSdkClient {
|
|||||||
return this.provider(modelId)
|
return this.provider(modelId)
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(`Unknown model access pattern for provider "${this.providerName}"`)
|
throw new Error(`Unknown model access pattern for provider "${this.options.name}"`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实现流式逻辑,使用核心ai-sdk函数
|
* 实现流式逻辑,使用核心ai-sdk函数
|
||||||
*/
|
*/
|
||||||
async stream(request: any): Promise<any> {
|
async stream(request: AiCoreRequest): Promise<StreamTextResult<any, any>> {
|
||||||
if (!this.initialized) await this.initialize()
|
if (!this.initialized) await this.initialize()
|
||||||
|
|
||||||
const model = this.getModel(request.modelId)
|
const model = this.getModel(request.modelId)
|
||||||
@ -96,7 +97,7 @@ export class UniversalAiSdkClient {
|
|||||||
/**
|
/**
|
||||||
* 实现非流式逻辑
|
* 实现非流式逻辑
|
||||||
*/
|
*/
|
||||||
async generate(request: any): Promise<any> {
|
async generate(request: AiCoreRequest): Promise<GenerateTextResult<any, any>> {
|
||||||
if (!this.initialized) await this.initialize()
|
if (!this.initialized) await this.initialize()
|
||||||
|
|
||||||
const model = this.getModel(request.modelId)
|
const model = this.getModel(request.modelId)
|
||||||
@ -113,7 +114,7 @@ export class UniversalAiSdkClient {
|
|||||||
validateConfig(): boolean {
|
validateConfig(): boolean {
|
||||||
try {
|
try {
|
||||||
// 基础验证
|
// 基础验证
|
||||||
if (!this.providerName) return false
|
if (!this.options.name) return false
|
||||||
if (!this.providerConfig) return false
|
if (!this.providerConfig) return false
|
||||||
|
|
||||||
// API Key验证(如果需要)
|
// API Key验证(如果需要)
|
||||||
@ -133,7 +134,7 @@ export class UniversalAiSdkClient {
|
|||||||
private requiresApiKey(): boolean {
|
private requiresApiKey(): boolean {
|
||||||
// 大多数云服务Provider都需要API Key
|
// 大多数云服务Provider都需要API Key
|
||||||
const noApiKeyProviders = ['local', 'ollama'] // 本地运行的Provider
|
const noApiKeyProviders = ['local', 'ollama'] // 本地运行的Provider
|
||||||
return !noApiKeyProviders.includes(this.providerName)
|
return !noApiKeyProviders.includes(this.options.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -162,7 +163,10 @@ export class UniversalAiSdkClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 工厂函数,方便创建客户端
|
// 工厂函数,方便创建客户端
|
||||||
export async function createUniversalClient(providerName: string, options: any = {}): Promise<UniversalAiSdkClient> {
|
export async function createUniversalClient(
|
||||||
|
providerName: string,
|
||||||
|
options: ProviderOptions
|
||||||
|
): Promise<UniversalAiSdkClient> {
|
||||||
const client = new UniversalAiSdkClient(providerName, options)
|
const client = new UniversalAiSdkClient(providerName, options)
|
||||||
await client.initialize()
|
await client.initialize()
|
||||||
return client
|
return client
|
||||||
@ -172,9 +176,9 @@ export async function createUniversalClient(providerName: string, options: any =
|
|||||||
export async function streamGeneration(
|
export async function streamGeneration(
|
||||||
providerName: string,
|
providerName: string,
|
||||||
modelId: string,
|
modelId: string,
|
||||||
messages: any[],
|
messages: CoreMessage[],
|
||||||
options: any = {}
|
options: any
|
||||||
): Promise<any> {
|
): Promise<StreamTextResult<any, any>> {
|
||||||
const client = await createUniversalClient(providerName, options)
|
const client = await createUniversalClient(providerName, options)
|
||||||
|
|
||||||
return client.stream({
|
return client.stream({
|
||||||
@ -188,9 +192,9 @@ export async function streamGeneration(
|
|||||||
export async function generateCompletion(
|
export async function generateCompletion(
|
||||||
providerName: string,
|
providerName: string,
|
||||||
modelId: string,
|
modelId: string,
|
||||||
messages: any[],
|
messages: CoreMessage[],
|
||||||
options: any = {}
|
options: any = {}
|
||||||
): Promise<any> {
|
): Promise<GenerateTextResult<any, any>> {
|
||||||
const client = await createUniversalClient(providerName, options)
|
const client = await createUniversalClient(providerName, options)
|
||||||
|
|
||||||
return client.generate({
|
return client.generate({
|
||||||
|
|||||||
23
packages/aiCore/src/clients/types.ts
Normal file
23
packages/aiCore/src/clients/types.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { CoreMessage } from 'ai'
|
||||||
|
|
||||||
|
export type ProviderOptions = {
|
||||||
|
name: string
|
||||||
|
apiKey?: string
|
||||||
|
apiHost: string
|
||||||
|
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>
|
||||||
|
}
|
||||||
@ -45,6 +45,12 @@ export class AiProviderRegistry {
|
|||||||
import: () => import('@ai-sdk/openai'),
|
import: () => import('@ai-sdk/openai'),
|
||||||
creatorFunctionName: 'createOpenAI'
|
creatorFunctionName: 'createOpenAI'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'openai-compatible',
|
||||||
|
name: 'OpenAI Compatible',
|
||||||
|
import: () => import('@ai-sdk/openai-compatible'),
|
||||||
|
creatorFunctionName: 'createOpenAICompatible'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'anthropic',
|
id: 'anthropic',
|
||||||
name: 'Anthropic',
|
name: 'Anthropic',
|
||||||
@ -152,6 +158,30 @@ export class AiProviderRegistry {
|
|||||||
name: 'Vercel',
|
name: 'Vercel',
|
||||||
import: () => import('@ai-sdk/vercel'),
|
import: () => import('@ai-sdk/vercel'),
|
||||||
creatorFunctionName: 'createVercel'
|
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'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user