mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-27 21:01:32 +08:00
chore: update release notes and version to 1.6.0-beta.6
- Refined performance optimizations for AI services and improved compatibility with various providers. - Enhanced error handling and stability in the ModernAiProvider class. - Updated version in package.json to 1.6.0-beta.6.
This commit is contained in:
parent
976d246cac
commit
01c4777691
@ -121,26 +121,12 @@ afterSign: scripts/notarize.js
|
||||
artifactBuildCompleted: scripts/artifact-build-completed.js
|
||||
releaseInfo:
|
||||
releaseNotes: |
|
||||
✨ 重要更新:
|
||||
- 增强Web搜索功能:重构搜索结果处理和展示逻辑
|
||||
- 优化知识库设置:默认关闭知识识别以提升性能
|
||||
- 新增Gemini 2.5 Flash Image模型的自动图像生成功能
|
||||
- 支持链接OG数据解析和预览展示
|
||||
- 增强OCR服务的Linux兼容性
|
||||
|
||||
🔧 性能优化:
|
||||
- 重构AI核心架构,采用现代化的AI SDK 5.0
|
||||
- 优化消息重试机制,新增"重试失败消息"按钮
|
||||
- 改进侧边栏动画效果和用户交互体验
|
||||
- 优化Vite构建系统,使用Rolldown引擎提升构建性能
|
||||
- 重构参数处理和文件处理模块
|
||||
- 优化API key轮转机制
|
||||
- 优化AI服务连接方式,提升响应速度和稳定性
|
||||
- 改进模型列表获取功能,减少不必要的网络请求
|
||||
- 增强各AI服务商的兼容性和连接可靠性
|
||||
|
||||
🐛 修复问题:
|
||||
- 修复tabs组件高度不足导致边框样式问题
|
||||
- 修复Gemini 2.5 Flash Image模型的图像生成按钮状态
|
||||
- 修复ModelScope DeepSeek v3.1思考模式问题
|
||||
- 修复PoeLogo在provider UI组件中的渲染问题
|
||||
- 修复ASAR集成相关问题
|
||||
- 移除加载状态阻塞输入的问题
|
||||
- 修复多个UI组件和样式问题
|
||||
🐛 问题修复:
|
||||
- 修复部分AI服务商连接失败的问题
|
||||
- 修复模型配置加载时的潜在错误
|
||||
- 提升应用整体稳定性和容错能力
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "CherryStudio",
|
||||
"version": "1.6.0-beta.5",
|
||||
"version": "1.6.0-beta.6",
|
||||
"private": true,
|
||||
"description": "A powerful AI assistant for producer.",
|
||||
"main": "./out/main/index.js",
|
||||
|
||||
@ -42,18 +42,36 @@ export type ModernAiProviderConfig = AiSdkMiddlewareConfig & {
|
||||
|
||||
export default class ModernAiProvider {
|
||||
private legacyProvider: LegacyAiProvider
|
||||
private config: ReturnType<typeof providerToAiSdkConfig>
|
||||
private config?: ReturnType<typeof providerToAiSdkConfig>
|
||||
private actualProvider: Provider
|
||||
private model: Model
|
||||
private model?: Model
|
||||
private localProvider: Awaited<AiSdkProvider> | null = null
|
||||
|
||||
constructor(model: Model, provider?: Provider) {
|
||||
this.actualProvider = provider || getActualProvider(model)
|
||||
this.legacyProvider = new LegacyAiProvider(this.actualProvider)
|
||||
this.model = model
|
||||
// 构造函数重载签名
|
||||
constructor(model: Model, provider?: Provider)
|
||||
constructor(provider: Provider)
|
||||
constructor(modelOrProvider: Model | Provider, provider?: Provider)
|
||||
constructor(modelOrProvider: Model | Provider, provider?: Provider) {
|
||||
if (this.isModel(modelOrProvider)) {
|
||||
// 传入的是 Model
|
||||
this.model = modelOrProvider
|
||||
this.actualProvider = provider || getActualProvider(modelOrProvider)
|
||||
// 只保存配置,不预先创建executor
|
||||
this.config = providerToAiSdkConfig(this.actualProvider, modelOrProvider)
|
||||
} else {
|
||||
// 传入的是 Provider
|
||||
this.actualProvider = modelOrProvider
|
||||
// model为可选,某些操作(如fetchModels)不需要model
|
||||
}
|
||||
|
||||
// 只保存配置,不预先创建executor
|
||||
this.config = providerToAiSdkConfig(this.actualProvider, model)
|
||||
this.legacyProvider = new LegacyAiProvider(this.actualProvider)
|
||||
}
|
||||
|
||||
/**
|
||||
* 类型守卫函数:通过 provider 属性区分 Model 和 Provider
|
||||
*/
|
||||
private isModel(obj: Model | Provider): obj is Model {
|
||||
return 'provider' in obj && typeof obj.provider === 'string'
|
||||
}
|
||||
|
||||
public getActualProvider() {
|
||||
@ -61,6 +79,16 @@ export default class ModernAiProvider {
|
||||
}
|
||||
|
||||
public async completions(modelId: string, params: StreamTextParams, config: ModernAiProviderConfig) {
|
||||
// 检查model是否存在
|
||||
if (!this.model) {
|
||||
throw new Error('Model is required for completions. Please use constructor with model parameter.')
|
||||
}
|
||||
|
||||
// 确保配置存在
|
||||
if (!this.config) {
|
||||
this.config = providerToAiSdkConfig(this.actualProvider, this.model)
|
||||
}
|
||||
|
||||
// 准备特殊配置
|
||||
await prepareSpecialProviderConfig(this.actualProvider, this.config)
|
||||
|
||||
@ -127,7 +155,7 @@ export default class ModernAiProvider {
|
||||
params: StreamTextParams,
|
||||
config: ModernAiProviderConfig & { topicId: string }
|
||||
): Promise<CompletionsResult> {
|
||||
const modelId = this.model.id
|
||||
const modelId = this.model!.id
|
||||
const traceName = `${this.actualProvider.name}.${modelId}.${config.callType}`
|
||||
const traceParams: StartSpanParams = {
|
||||
name: traceName,
|
||||
@ -211,10 +239,10 @@ export default class ModernAiProvider {
|
||||
params: StreamTextParams,
|
||||
config: ModernAiProviderConfig
|
||||
): Promise<CompletionsResult> {
|
||||
const modelId = this.model.id
|
||||
const modelId = this.model!.id
|
||||
logger.info('Starting modernCompletions', {
|
||||
modelId,
|
||||
providerId: this.config.providerId,
|
||||
providerId: this.config!.providerId,
|
||||
topicId: config.topicId,
|
||||
hasOnChunk: !!config.onChunk,
|
||||
hasTools: !!params.tools && Object.keys(params.tools).length > 0,
|
||||
@ -225,11 +253,11 @@ export default class ModernAiProvider {
|
||||
const plugins = buildPlugins(config)
|
||||
|
||||
// 用构建好的插件数组创建executor
|
||||
const executor = createExecutor(this.config.providerId, this.config.options, plugins)
|
||||
const executor = createExecutor(this.config!.providerId, this.config!.options, plugins)
|
||||
|
||||
// 创建带有中间件的执行器
|
||||
if (config.onChunk) {
|
||||
const accumulate = this.model.supported_text_delta !== false // true and undefined
|
||||
const accumulate = this.model!.supported_text_delta !== false // true and undefined
|
||||
const adapter = new AiSdkToChunkAdapter(config.onChunk, config.mcpTools, accumulate)
|
||||
|
||||
const streamResult = await executor.streamText({
|
||||
@ -308,7 +336,7 @@ export default class ModernAiProvider {
|
||||
}
|
||||
|
||||
// 调用新 AI SDK 的图像生成功能
|
||||
const executor = createExecutor(this.config.providerId, this.config.options, [])
|
||||
const executor = createExecutor(this.config!.providerId, this.config!.options, [])
|
||||
const result = await executor.generateImage({
|
||||
model,
|
||||
...imageParams
|
||||
@ -428,7 +456,7 @@ export default class ModernAiProvider {
|
||||
...(signal && { abortSignal: signal })
|
||||
}
|
||||
|
||||
const executor = createExecutor(this.config.providerId, this.config.options, [])
|
||||
const executor = createExecutor(this.config!.providerId, this.config!.options, [])
|
||||
const result = await executor.generateImage({
|
||||
model: this.localProvider?.imageModel(model) as ImageModel,
|
||||
...aiSdkParams
|
||||
|
||||
@ -131,12 +131,21 @@ export function providerToAiSdkConfig(
|
||||
// 添加额外headers
|
||||
if (actualProvider.extra_headers) {
|
||||
extraOptions.headers = actualProvider.extra_headers
|
||||
// copy from openaiBaseClient/openaiResponseApiClient
|
||||
if (aiSdkProviderId === 'openai') {
|
||||
extraOptions.headers = {
|
||||
...extraOptions.headers,
|
||||
'HTTP-Referer': 'https://cherry-ai.com',
|
||||
'X-Title': 'Cherry Studio',
|
||||
'X-Api-Key': baseConfig.apiKey
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copilot
|
||||
if (actualProvider.id === 'copilot') {
|
||||
extraOptions.headers = {
|
||||
...extraOptions.extra_headers,
|
||||
...extraOptions.headers,
|
||||
'editor-version': 'vscode/1.97.2',
|
||||
'copilot-vision-request': 'true'
|
||||
}
|
||||
@ -183,7 +192,6 @@ export function providerToAiSdkConfig(
|
||||
} else if (baseConfig.baseURL.endsWith('/v1')) {
|
||||
baseConfig.baseURL = baseConfig.baseURL.slice(0, -3)
|
||||
}
|
||||
|
||||
baseConfig.baseURL = isEmpty(baseConfig.baseURL) ? '' : baseConfig.baseURL
|
||||
}
|
||||
|
||||
|
||||
@ -350,7 +350,7 @@ export function hasApiKey(provider: Provider) {
|
||||
// }
|
||||
|
||||
export async function fetchModels(provider: Provider): Promise<SdkModel[]> {
|
||||
const AI = new AiProviderNew({} as Model, provider)
|
||||
const AI = new AiProviderNew(provider)
|
||||
|
||||
try {
|
||||
return await AI.models()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user