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:
suyao 2025-06-17 19:28:21 +08:00
parent 7187e63ce2
commit b771873f6c
5 changed files with 1536 additions and 17 deletions

View File

@ -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"
} }

File diff suppressed because it is too large Load Diff

View File

@ -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({

View 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>
}

View File

@ -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'
} }
] ]