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