Compare commits

..

6 Commits

Author SHA1 Message Date
defi-failure
9f00f00546 chore: update v1.7.0-beta.3 release notes (#11105)
* chore: update v1.7.0-beta.3 release notes

* fix(i18n): Auto update translations for PR #11105

* fix: code lint error

---------

Co-authored-by: GitHub Action <action@github.com>
2025-11-02 22:28:36 +08:00
SuYao
bd94d23343 refactor:Unify the naming of configuration fields in thinking, change to using underscore style. (#11106)
* refactor:Unify the naming of configuration fields in thinking, change to using underscore style.

* fix(i18n): Auto update translations for PR #11106

* chore: lint

* fix: typecheck

---------

Co-authored-by: GitHub Action <action@github.com>
2025-11-02 19:24:23 +08:00
chenxue
5f1c14e2c0 fix(aihubmix): fix default rules missing app code (#11100)
* add imagen

* Update aihubmix.ts

* fix type

---------

Co-authored-by: zhaochenxue <zhaochenxue@bixin.cn>
2025-11-02 17:03:05 +08:00
dependabot[bot]
cdc12d5092 ci(deps): bump actions/stale from 9 to 10 (#11088)
Bumps [actions/stale](https://github.com/actions/stale) from 9 to 10.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v9...v10)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-version: '10'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-02 08:44:53 +08:00
dependabot[bot]
e5967fd874 ci(deps): bump actions/upload-artifact from 4 to 5 (#11089)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-02 08:44:41 +08:00
dependabot[bot]
e2f1d80697 ci(deps): bump actions/setup-node from 4 to 6 (#11090)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-02 08:44:28 +08:00
22 changed files with 86 additions and 165 deletions

View File

@@ -27,7 +27,7 @@ jobs:
ref: ${{ github.event.pull_request.head.ref }}
- name: 📦 Setting Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@v6
with:
node-version: 20
package-manager-cache: false

View File

@@ -54,7 +54,7 @@ jobs:
- name: Setup Node.js
if: steps.check_time.outputs.should_delay == 'false'
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: '20'
@@ -121,7 +121,7 @@ jobs:
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: '20'

View File

@@ -21,7 +21,7 @@ jobs:
contents: none
steps:
- name: Close needs-more-info issues
uses: actions/stale@v9
uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
only-labels: 'needs-more-info'
@@ -42,7 +42,7 @@ jobs:
days-before-pr-close: -1
- name: Close inactive issues
uses: actions/stale@v9
uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: ${{ env.daysBeforeStale }}

View File

@@ -56,7 +56,7 @@ jobs:
ref: main
- name: Install Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@v6
with:
node-version: 20
@@ -208,7 +208,7 @@ jobs:
echo "总计: $(find renamed-artifacts -type f | wc -l) 个文件"
- name: Upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: cherry-studio-nightly-${{ steps.date.outputs.date }}-${{ matrix.os }}
path: renamed-artifacts/*

View File

@@ -24,7 +24,7 @@ jobs:
uses: actions/checkout@v5
- name: Install Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@v6
with:
node-version: 20

View File

@@ -47,7 +47,7 @@ jobs:
npm version "$VERSION" --no-git-tag-version --allow-same-version
- name: Install Node.js
uses: actions/setup-node@v5
uses: actions/setup-node@v6
with:
node-version: 20

View File

@@ -161,6 +161,9 @@ releaseInfo:
- MCP Confirmation: Added confirmation modal when activating protocol-installed MCP servers
- Translation: Enhanced translation script with concurrency and validation
- Electron & Vite: Updated to Electron 38 and Vite 4.0.1
- QR Code Generation: Optimized performance for phone LAN export
- Enterprise Settings: Added enterprise section in About settings
- Assistant/Agent Popup: Enhanced UI for adding assistants and agents
Claude Code Tool Improvements:
- GlobTool: Now counts lines instead of files in output for better clarity
@@ -188,6 +191,9 @@ releaseInfo:
- Fixed reranker API error response capture
- Fixed right-click paste file content into inputbar
- Fixed minimax-m2 support in aiCore
- Fixed Azure embedding issues
- Fixed agent edit modal loading race condition
- Fixed debounced save cancellation on file path update
<!--LANG:zh-CN-->
v1.7.0-beta.3 新特性
@@ -218,6 +224,9 @@ releaseInfo:
- MCP 确认:添加激活协议安装的 MCP 服务器时的确认模态框
- 翻译:增强翻译脚本的并发和验证功能
- Electron & Vite更新至 Electron 38 和 Vite 4.0.1
- 二维码生成:优化手机局域网导出性能
- 企业设置:在关于设置中添加企业部分
- 助手/Agent 弹窗:增强添加助手和 Agent 的界面
Claude Code 工具改进:
- GlobTool现在计算行数而不是文件数提供更清晰的输出
@@ -245,4 +254,7 @@ releaseInfo:
- 修复 reranker API 错误响应捕获
- 修复右键粘贴文件内容到输入栏
- 修复 aiCore 中的 minimax-m2 支持
- 修复 Azure embedding 问题
- 修复 Agent 编辑模态框加载竞态条件
- 修复文件路径更新时防抖保存取消问题
<!--LANG:END-->

View File

@@ -1,5 +1,5 @@
import { loggerService } from '@logger'
import { WebSocketCandidatesResponse, WebSocketStatusResponse } from '@shared/config/types'
import type { WebSocketCandidatesResponse, WebSocketStatusResponse } from '@shared/config/types'
import * as fs from 'fs'
import { networkInterfaces } from 'os'
import * as path from 'path'

View File

@@ -192,7 +192,7 @@ export class OpenAIAPIClient extends OpenAIBaseClient<
extra_body: {
google: {
thinking_config: {
thinkingBudget: 0
thinking_budget: 0
}
}
}
@@ -327,8 +327,8 @@ export class OpenAIAPIClient extends OpenAIBaseClient<
extra_body: {
google: {
thinking_config: {
thinkingBudget: -1,
includeThoughts: true
thinking_budget: -1,
include_thoughts: true
}
}
}
@@ -338,8 +338,8 @@ export class OpenAIAPIClient extends OpenAIBaseClient<
extra_body: {
google: {
thinking_config: {
thinkingBudget: budgetTokens,
includeThoughts: true
thinking_budget: budgetTokens,
include_thoughts: true
}
}
}
@@ -670,7 +670,7 @@ export class OpenAIAPIClient extends OpenAIBaseClient<
} else if (isClaudeReasoningModel(model) && reasoningEffort.thinking?.budget_tokens) {
suffix = ` --thinking_budget ${reasoningEffort.thinking.budget_tokens}`
} else if (isGeminiReasoningModel(model) && reasoningEffort.extra_body?.google?.thinking_config) {
suffix = ` --thinking_budget ${reasoningEffort.extra_body.google.thinking_config.thinkingBudget}`
suffix = ` --thinking_budget ${reasoningEffort.extra_body.google.thinking_config.thinking_budget}`
}
// FIXME: poe 不支持多个text part上传文本文件的时候用的不是file part而是text part因此会出问题
// 临时解决方案是强制poe用string content但是其实poe部分支持array

View File

@@ -52,7 +52,7 @@ const AIHUBMIX_RULES: RuleSet = {
}
}
],
fallbackRule: (provider: Provider) => provider
fallbackRule: (provider: Provider) => extraProviderConfig(provider)
}
export const aihubmixProviderCreator = provider2Provider.bind(null, AIHUBMIX_RULES)

View File

@@ -98,7 +98,7 @@ export function getReasoningEffort(assistant: Assistant, model: Model): Reasonin
extra_body: {
google: {
thinking_config: {
thinkingBudget: 0
thinking_budget: 0
}
}
}
@@ -259,8 +259,8 @@ export function getReasoningEffort(assistant: Assistant, model: Model): Reasonin
extra_body: {
google: {
thinking_config: {
thinkingBudget: -1,
includeThoughts: true
thinking_budget: -1,
include_thoughts: true
}
}
}
@@ -270,8 +270,8 @@ export function getReasoningEffort(assistant: Assistant, model: Model): Reasonin
extra_body: {
google: {
thinking_config: {
thinkingBudget: budgetTokens,
includeThoughts: true
thinking_budget: budgetTokens ?? -1,
include_thoughts: true
}
}
}
@@ -431,8 +431,8 @@ export function getGeminiReasoningParams(assistant: Assistant, model: Model): Re
if (reasoningEffort === undefined) {
return {
thinkingConfig: {
includeThoughts: false,
...(GEMINI_FLASH_MODEL_REGEX.test(model.id) ? { thinkingBudget: 0 } : {})
include_thoughts: false,
...(GEMINI_FLASH_MODEL_REGEX.test(model.id) ? { thinking_budget: 0 } : {})
}
}
}
@@ -442,7 +442,7 @@ export function getGeminiReasoningParams(assistant: Assistant, model: Model): Re
if (effortRatio > 1) {
return {
thinkingConfig: {
includeThoughts: true
include_thoughts: true
}
}
}
@@ -452,8 +452,8 @@ export function getGeminiReasoningParams(assistant: Assistant, model: Model): Re
return {
thinkingConfig: {
...(budget > 0 ? { thinkingBudget: budget } : {}),
includeThoughts: true
...(budget > 0 ? { thinking_budget: budget } : {}),
include_thoughts: true
}
}
}

View File

@@ -5,7 +5,7 @@ import { Spinner } from '@heroui/spinner'
import { loggerService } from '@logger'
import { AppLogo } from '@renderer/config/env'
import { SettingHelpText, SettingRow } from '@renderer/pages/settings'
import { WebSocketCandidatesResponse } from '@shared/config/types'
import type { WebSocketCandidatesResponse } from '@shared/config/types'
import { QRCodeSVG } from 'qrcode.react'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Bewältigen Sie komplexe Aufgaben mit verschiedenen Werkzeugen",
"error": {
"failed": "Agent hinzufügen fehlgeschlagen",
"invalid_agent": "Ungültiger Agent"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Tägliche Gespräche und schnelle Fragen & Antworten",
"title": "Assistent hinzufügen"
},
"option": {
"title": "Typ auswählen"
},
"topic": {
"title": "Neues Thema erstellen"
}

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Χειριστείτε πολύπλοκες εργασίες με διάφορα εργαλεία",
"error": {
"failed": "Αποτυχία προσθήκης πράκτορα",
"invalid_agent": "Μη έγκυρος Agent"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Καθημερινές συνομιλίες και γρήγορες ερωταπαντήσεις",
"title": "Προσθήκη βοηθού"
},
"option": {
"title": "Επιλέξτε Τύπο"
},
"topic": {
"title": "Δημιουργία νέου θέματος"
}

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Maneja tareas complejas con varias herramientas",
"error": {
"failed": "Error al añadir agente",
"invalid_agent": "Agent inválido"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Conversaciones diarias y preguntas y respuestas rápidas",
"title": "Agregar asistente"
},
"option": {
"title": "Seleccionar Tipo"
},
"topic": {
"title": "Crear nuevo tema"
}

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Gérez des tâches complexes avec divers outils",
"error": {
"failed": "Échec de l'ajout de l'agent",
"invalid_agent": "Agent invalide"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Conversations quotidiennes et Q&R rapides",
"title": "Ajouter un assistant"
},
"option": {
"title": "Sélectionner le type"
},
"topic": {
"title": "Nouveau sujet"
}

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "さまざまなツールを使って複雑なタスクを処理する",
"error": {
"failed": "エージェントの追加に失敗しました",
"invalid_agent": "無効なエージェント"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "日常会話と簡単なQ&A",
"title": "アシスタントを追加"
},
"option": {
"title": "種類を選択"
},
"topic": {
"title": "新しいトピック"
}

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Lide com tarefas complexas usando várias ferramentas",
"error": {
"failed": "Falha ao adicionar agente",
"invalid_agent": "Agent inválido"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Conversas diárias e perguntas e respostas rápidas",
"title": "Adicionar assistente"
},
"option": {
"title": "Selecionar Tipo"
},
"topic": {
"title": "Novo Tópico"
}

View File

@@ -1,6 +1,7 @@
{
"agent": {
"add": {
"description": "Справляйтесь со сложными задачами с помощью различных инструментов",
"error": {
"failed": "Не удалось добавить агента",
"invalid_agent": "Недействительный агент"
@@ -547,8 +548,12 @@
"chat": {
"add": {
"assistant": {
"description": "Ежедневные разговоры и быстрые вопросы и ответы",
"title": "Добавить ассистента"
},
"option": {
"title": "Выберите тип"
},
"topic": {
"title": "Новый топик"
}

View File

@@ -23,7 +23,6 @@ import type {
GoogleGenAI,
Model as GeminiModel,
SendMessageParameters,
ThinkingConfig,
Tool
} from '@google/genai'
@@ -92,7 +91,10 @@ export type ReasoningEffortOptionalParams = {
}
extra_body?: {
google?: {
thinking_config: ThinkingConfig
thinking_config: {
thinking_budget: number
include_thoughts?: boolean
}
}
}
// Add any other potential reasoning-related keys here if they exist

View File

@@ -1,128 +0,0 @@
import { describe, expect, it } from 'vitest'
import { mcpToolsToOpenAIChatTools, mcpToolsToOpenAIResponseTools } from '../mcp-tools'
import type { MCPTool } from '@renderer/types'
describe('MCP Tools - HTTP MCP Compatibility Fix', () => {
const mockMCPTool: MCPTool = {
id: 'test_server-search_tool',
name: 'search_tool',
description: 'Search for information',
inputSchema: {
type: 'object',
properties: {
query: {
type: 'string',
description: 'Search query'
},
limit: {
type: 'number',
description: 'Optional limit',
minimum: 1
}
},
required: ['query'] // Only query is required, limit is optional
},
serverId: 'test-server-id',
serverName: 'test-server',
type: 'mcp'
}
describe('mcpToolsToOpenAIResponseTools', () => {
it('should preserve original schema without forcing all properties to be required', () => {
const tools = mcpToolsToOpenAIResponseTools([mockMCPTool])
expect(tools).toHaveLength(1)
const tool = tools[0]
// Should use the tool id
expect(tool.name).toBe('test_server-search_tool')
// Should preserve the original required array (only 'query')
expect(tool.parameters.required).toEqual(['query'])
// Should have both properties
expect(tool.parameters.properties).toHaveProperty('query')
expect(tool.parameters.properties).toHaveProperty('limit')
})
it('should not include strict: true', () => {
const tools = mcpToolsToOpenAIResponseTools([mockMCPTool])
expect(tools).toHaveLength(1)
const tool = tools[0] as any
// strict property should not be present
expect(tool.strict).toBeUndefined()
})
})
describe('mcpToolsToOpenAIChatTools', () => {
it('should preserve original schema without forcing all properties to be required', () => {
const tools = mcpToolsToOpenAIChatTools([mockMCPTool])
expect(tools).toHaveLength(1)
const tool = tools[0]
// Should use the tool id
expect(tool.function.name).toBe('test_server-search_tool')
// Should include description
expect(tool.function.description).toBe('Search for information')
// Should preserve the original required array (only 'query')
expect(tool.function.parameters.required).toEqual(['query'])
// Should have both properties
expect(tool.function.parameters.properties).toHaveProperty('query')
expect(tool.function.parameters.properties).toHaveProperty('limit')
})
it('should not include strict: true in function parameters', () => {
const tools = mcpToolsToOpenAIChatTools([mockMCPTool])
expect(tools).toHaveLength(1)
const tool = tools[0] as any
// strict property should not be present
expect(tool.function.strict).toBeUndefined()
})
})
describe('HTTP MCP with complex nested schemas', () => {
it('should handle nested objects with optional fields', () => {
const complexTool: MCPTool = {
id: 'http_server-complex_tool',
name: 'complex_tool',
description: 'Complex tool with nested schemas',
inputSchema: {
type: 'object',
properties: {
required_field: { type: 'string' },
optional_object: {
type: 'object',
properties: {
nested_required: { type: 'string' },
nested_optional: { type: 'number' }
},
required: ['nested_required']
}
},
required: ['required_field']
},
serverId: 'http-server-id',
serverName: 'http-server',
type: 'mcp'
}
const tools = mcpToolsToOpenAIChatTools([complexTool])
const parameters = tools[0].function.parameters
// Top level should only require 'required_field'
expect(parameters.required).toEqual(['required_field'])
// Nested object should only require 'nested_required'
expect(parameters.properties.optional_object.required).toEqual(['nested_required'])
})
})
})

View File

@@ -32,14 +32,13 @@ import { nanoid } from 'nanoid'
import { isToolUseModeFunction } from './assistant'
import { convertBase64ImageToAwsBedrockFormat } from './aws-bedrock-utils'
import { filterProperties } from './mcp-schema'
import { filterProperties, processSchemaForO3 } from './mcp-schema'
const logger = loggerService.withContext('Utils:MCPTools')
export function mcpToolsToOpenAIResponseTools(mcpTools: MCPTool[]): OpenAI.Responses.Tool[] {
return mcpTools.map((tool) => {
// Use the original schema without strict mode processing to maintain compatibility with all MCP types
const parameters = tool.inputSchema
const parameters = processSchemaForO3(tool.inputSchema)
return {
type: 'function',
@@ -47,15 +46,15 @@ export function mcpToolsToOpenAIResponseTools(mcpTools: MCPTool[]): OpenAI.Respo
parameters: {
type: 'object' as const,
...parameters
}
},
strict: true
} satisfies OpenAI.Responses.Tool
})
}
export function mcpToolsToOpenAIChatTools(mcpTools: MCPTool[]): Array<ChatCompletionTool> {
return mcpTools.map((tool) => {
// Use the original schema without strict mode processing to maintain compatibility with all MCP types
const parameters = tool.inputSchema
const parameters = processSchemaForO3(tool.inputSchema)
return {
type: 'function',
@@ -65,7 +64,8 @@ export function mcpToolsToOpenAIChatTools(mcpTools: MCPTool[]): Array<ChatComple
parameters: {
type: 'object' as const,
...parameters
}
},
strict: true
}
} as ChatCompletionTool
})