diff --git a/.github/workflows/claude-translator.yml b/.github/workflows/claude-translator.yml
index ab2b6f7e4f..ff317f8532 100644
--- a/.github/workflows/claude-translator.yml
+++ b/.github/workflows/claude-translator.yml
@@ -1,6 +1,6 @@
name: Claude Translator
concurrency:
- group: translator-${{ github.event.comment.id || github.event.issue.number }}
+ group: translator-${{ github.event.comment.id || github.event.issue.number || github.event.review.id }}
cancel-in-progress: false
on:
@@ -8,14 +8,18 @@ on:
types: [opened]
issue_comment:
types: [created, edited]
+ pull_request_review:
+ types: [submitted, edited]
+ pull_request_review_comment:
+ types: [created, edited]
jobs:
translate:
if: |
(github.event_name == 'issues') ||
- (github.event_name == 'issue_comment' && github.event.sender.type != 'Bot') &&
- ((github.event_name == 'issue_comment' && github.event.action == 'created' && !contains(github.event.comment.body, 'This issue was translated by Claude')) ||
- (github.event_name == 'issue_comment' && github.event.action == 'edited'))
+ (github.event_name == 'issue_comment' && github.event.sender.type != 'Bot') ||
+ (github.event_name == 'pull_request_review' && github.event.sender.type != 'Bot') ||
+ (github.event_name == 'pull_request_review_comment' && github.event.sender.type != 'Bot')
runs-on: ubuntu-latest
permissions:
contents: read
@@ -37,23 +41,44 @@ jobs:
# Now `contents: read` is safe for files, but we could make a fine-grained token to control it.
# See: https://github.com/anthropics/claude-code-action/blob/main/docs/security.md
github_token: ${{ secrets.TOKEN_GITHUB_WRITE }}
- allowed_non_write_users: '*'
+ allowed_non_write_users: "*"
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
- claude_args: '--allowed-tools Bash(gh issue:*),Bash(gh api:repos/*/issues:*)'
+ claude_args: "--allowed-tools Bash(gh issue:*),Bash(gh api:repos/*/issues:*),Bash(gh api:repos/*/pulls/*/reviews/*),Bash(gh api:repos/*/pulls/comments/*)"
prompt: |
- 你是一个多语言翻译助手。请完成以下任务:
+ 你是一个多语言翻译助手。你需要响应 GitHub Webhooks 中的以下四种事件:
+
+ - issues
+ - issue_comment
+ - pull_request_review
+ - pull_request_review_comment
+
+ 请完成以下任务:
+
+ 1. 获取当前事件的完整信息。
+
+ - 如果当前事件是 issues,就获取该 issues 的信息。
+ - 如果当前事件是 issue_comment,就获取该 comment 的信息。
+ - 如果当前事件是 pull_request_review,就获取该 review 的信息。
+ - 如果当前事件是 pull_request_review_comment,就获取该 comment 的信息。
- 1. 获取当前issue/comment的完整信息
2. 智能检测内容。
- 1. 如果是已经遵循格式要求翻译过的issue/comment,检查翻译内容和原始内容是否匹配。若不匹配,则重新翻译一次令其匹配,并遵循格式要求;若匹配,则跳过任务。
- 2. 如果是未翻译过的issue/comment,检查其内容语言。若不是英文,则翻译成英文;若已经是英文,则跳过任务。
+
+ - 如果获取到的信息是已经遵循格式要求翻译过的内容,则检查翻译内容和原始内容是否匹配。若不匹配,则重新翻译一次令其匹配,并遵循格式要求;
+ - 如果获取到的信息是未翻译过的内容,检查其内容语言。若不是英文,则翻译成英文;
+ - 如果获取到的信息是部分翻译为英文的内容,则将其翻译为英文;
+ - 如果获取到的信息包含了对已翻译内容的引用,则将引用内容清理为仅含英文的内容。引用的内容不能够包含"This xxx was translated by Claude"和"Original Content`等内容。
+ - 如果获取到的信息包含了其他类型的引用,即对非 Claude 翻译的内容的引用,则直接照原样引用,不进行翻译。
+ - 如果获取到的信息是通过邮件回复的内容,则在翻译时应当将邮件内容的引用放到最后。在原始内容和翻译内容中只需要回复的内容本身,不要包含对邮件内容的引用。
+ - 如果获取到的信息本身不需要任何处理,则跳过任务。
+
3. 格式要求:
+
- 标题:英文翻译(如果非英文)
- 内容格式:
> [!NOTE]
- > This issue/comment was translated by Claude.
+ > This issue/comment/review was translated by Claude.
- [英文翻译内容]
+ [翻译内容]
---
@@ -62,15 +87,21 @@ jobs:
4. 使用gh工具更新:
+
- 根据环境信息中的Event类型选择正确的命令:
- - 如果Event是'issues':gh issue edit [ISSUE_NUMBER] --title "[英文标题]" --body "[翻译内容 + 原始内容]"
- - 如果Event是'issue_comment':gh api -X PATCH /repos/[REPO]/issues/comments/[COMMENT_ID] -f body="[翻译内容 + 原始内容]"
+ - 如果 Event 是 'issues': gh issue edit [ISSUE_NUMBER] --title "[英文标题]" --body "[翻译内容 + 原始内容]"
+ - 如果 Event 是 'issue_comment': gh api -X PATCH /repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }} -f body="[翻译内容 + 原始内容]"
+ - 如果 Event 是 'pull_request_review': gh api -X PUT /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews/${{ github.event.review.id }} -f body="[翻译内容]"
+ - 如果 Event 是 'pull_request_review_comment': gh api -X PATCH /repos/${{ github.repository }}/pulls/comments/${{ github.event.comment.id }} -f body="[翻译内容 + 原始内容]"
环境信息:
- Event: ${{ github.event_name }}
- Issue Number: ${{ github.event.issue.number }}
- Repository: ${{ github.repository }}
- - Comment ID: ${{ github.event.comment.id || 'N/A' }} (only available for comment events)
+ - (Review) Comment ID: ${{ github.event.comment.id || 'N/A' }}
+ - Pull Request Number: ${{ github.event.pull_request.number || 'N/A' }}
+ - Review ID: ${{ github.event.review.id || 'N/A' }}
+
使用以下命令获取完整信息:
gh issue view ${{ github.event.issue.number }} --json title,body,comments
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index a08379caed..79046aa441 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -6,7 +6,6 @@
"bradlc.vscode-tailwindcss",
"vitest.explorer",
"oxc.oxc-vscode",
- "biomejs.biome",
- "typescriptteam.native-preview"
+ "biomejs.biome"
]
}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index eeac67e316..81bbc41671 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -47,6 +47,5 @@
"search.exclude": {
"**/dist/**": true,
".yarn/releases/**": true
- },
- "typescript.experimental.useTsgo": true
+ }
}
diff --git a/electron-builder.yml b/electron-builder.yml
index 80722308e4..6b7056ed3a 100644
--- a/electron-builder.yml
+++ b/electron-builder.yml
@@ -125,25 +125,16 @@ afterSign: scripts/notarize.js
artifactBuildCompleted: scripts/artifact-build-completed.js
releaseInfo:
releaseNotes: |
- ✨ 新功能:
- - 重构知识库模块,提升文档处理能力和搜索性能
- - 新增 PaddleOCR 支持,增强文档识别能力
- - 支持自定义窗口控制按钮样式
- - 新增 AI SDK 包,扩展 AI 能力集成
- - 支持标签页拖拽重排序功能
- - 增强笔记编辑器的同步和日志功能
-
- 🔧 性能优化:
- - 优化 MCP 服务的日志记录和错误处理
- - 改进 WebView 服务的 User-Agent 处理
- - 优化迷你应用的标题栏样式和状态栏适配
- - 重构依赖管理,清理和优化 package.json
-
🐛 问题修复:
- - 修复输入栏无限状态更新循环问题
- - 修复窗口控制提示框的鼠标悬停延迟
- - 修复翻译输入框粘贴多内容源的处理
- - 修复导航服务初始化时序问题
- - 修复 MCP 通过 JSON 添加时的参数转换
- - 修复模型作用域服务器同步时的 URL 格式
- - 标准化工具提示图标样式
+ - 修复 Anthropic API URL 处理,移除尾部斜杠并添加端点路径处理
+ - 修复 MessageEditor 缺少 QuickPanelProvider 包装的问题
+ - 修复 MiniWindow 高度问题
+
+ 🚀 性能优化:
+ - 优化输入栏提及模型状态缓存,在渲染间保持状态
+ - 重构网络搜索参数支持模型内置搜索,新增 OpenAI Chat 和 OpenRouter 支持
+
+ 🔧 重构改进:
+ - 更新 HeroUIProvider 导入路径,改善上下文管理
+ - 更新依赖项和 VSCode 开发环境配置
+ - 升级 @cherrystudio/ai-core 到 v1.0.0-alpha.17
diff --git a/package.json b/package.json
index 41b243339d..8c7c73627b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "CherryStudio",
- "version": "1.6.0-beta.7",
+ "version": "1.6.0-rc.2",
"private": true,
"description": "A powerful AI assistant for producer.",
"main": "./out/main/index.js",
@@ -116,7 +116,7 @@
"@aws-sdk/client-bedrock-runtime": "^3.840.0",
"@aws-sdk/client-s3": "^3.840.0",
"@biomejs/biome": "2.2.4",
- "@cherrystudio/ai-core": "workspace:^1.0.0-alpha.16",
+ "@cherrystudio/ai-core": "workspace:^1.0.0-alpha.18",
"@cherrystudio/embedjs": "^0.1.31",
"@cherrystudio/embedjs-libsql": "^0.1.31",
"@cherrystudio/embedjs-loader-csv": "^0.1.31",
@@ -246,7 +246,6 @@
"diff": "^8.0.2",
"docx": "^9.0.2",
"dompurify": "^3.2.6",
- "dotenv": "^17.2.2",
"dotenv-cli": "^7.4.2",
"drizzle-kit": "^0.31.4",
"electron": "37.4.0",
@@ -344,7 +343,7 @@
"tsx": "^4.20.3",
"turndown-plugin-gfm": "^1.0.2",
"tw-animate-css": "^1.3.8",
- "typescript": "^5.6.2",
+ "typescript": "~5.8.2",
"undici": "6.21.2",
"unified": "^11.0.5",
"uuid": "^13.0.0",
@@ -385,11 +384,11 @@
"packageManager": "yarn@4.9.1",
"lint-staged": {
"*.{js,jsx,ts,tsx,cjs,mjs,cts,mts}": [
- "biome format --write",
+ "biome format --write --no-errors-on-unmatched",
"eslint --fix"
],
"*.{json,yml,yaml,css,html}": [
- "biome format --write"
+ "biome format --write --no-errors-on-unmatched"
]
}
}
diff --git a/packages/aiCore/package.json b/packages/aiCore/package.json
index 292b679d82..75ed6ea34e 100644
--- a/packages/aiCore/package.json
+++ b/packages/aiCore/package.json
@@ -1,6 +1,6 @@
{
"name": "@cherrystudio/ai-core",
- "version": "1.0.0-alpha.16",
+ "version": "1.0.0-alpha.18",
"description": "Cherry Studio AI Core - Unified AI Provider Interface Based on Vercel AI SDK",
"main": "dist/index.js",
"module": "dist/index.mjs",
diff --git a/packages/aiCore/src/core/options/factory.ts b/packages/aiCore/src/core/options/factory.ts
index 4350e9241b..ffeb15185c 100644
--- a/packages/aiCore/src/core/options/factory.ts
+++ b/packages/aiCore/src/core/options/factory.ts
@@ -59,7 +59,7 @@ export function createGoogleOptions(options: ExtractProviderOptions<'google'>) {
/**
* 创建OpenRouter供应商选项的便捷函数
*/
-export function createOpenRouterOptions(options: ExtractProviderOptions<'openrouter'>) {
+export function createOpenRouterOptions(options: ExtractProviderOptions<'openrouter'> | Record) {
return createProviderOptions('openrouter', options)
}
diff --git a/packages/aiCore/src/core/options/openrouter.ts b/packages/aiCore/src/core/options/openrouter.ts
deleted file mode 100644
index b351f8fda1..0000000000
--- a/packages/aiCore/src/core/options/openrouter.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-export type OpenRouterProviderOptions = {
- models?: string[]
-
- /**
- * https://openrouter.ai/docs/use-cases/reasoning-tokens
- * One of `max_tokens` or `effort` is required.
- * If `exclude` is true, reasoning will be removed from the response. Default is false.
- */
- reasoning?: {
- exclude?: boolean
- } & (
- | {
- max_tokens: number
- }
- | {
- effort: 'high' | 'medium' | 'low'
- }
- )
-
- /**
- * A unique identifier representing your end-user, which can
- * help OpenRouter to monitor and detect abuse.
- */
- user?: string
-
- extraBody?: Record
-
- /**
- * Enable usage accounting to get detailed token usage information.
- * https://openrouter.ai/docs/use-cases/usage-accounting
- */
- usage?: {
- /**
- * When true, includes token usage information in the response.
- */
- include: boolean
- }
-}
diff --git a/packages/aiCore/src/core/options/types.ts b/packages/aiCore/src/core/options/types.ts
index 724dc30698..8571fd2296 100644
--- a/packages/aiCore/src/core/options/types.ts
+++ b/packages/aiCore/src/core/options/types.ts
@@ -2,9 +2,8 @@ import { type AnthropicProviderOptions } from '@ai-sdk/anthropic'
import { type GoogleGenerativeAIProviderOptions } from '@ai-sdk/google'
import { type OpenAIResponsesProviderOptions } from '@ai-sdk/openai'
import { type SharedV2ProviderMetadata } from '@ai-sdk/provider'
-
-import { type OpenRouterProviderOptions } from './openrouter'
-import { type XaiProviderOptions } from './xai'
+import { type XaiProviderOptions } from '@ai-sdk/xai'
+import { type OpenRouterProviderOptions } from '@openrouter/ai-sdk-provider'
export type ProviderOptions = SharedV2ProviderMetadata[T]
diff --git a/packages/aiCore/src/core/options/xai.ts b/packages/aiCore/src/core/options/xai.ts
deleted file mode 100644
index 7fe5672778..0000000000
--- a/packages/aiCore/src/core/options/xai.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-// copy from @ai-sdk/xai/xai-chat-options.ts
-// 如果@ai-sdk/xai暴露出了xaiProviderOptions就删除这个文件
-
-import { z } from 'zod'
-
-const webSourceSchema = z.object({
- type: z.literal('web'),
- country: z.string().length(2).optional(),
- excludedWebsites: z.array(z.string()).max(5).optional(),
- allowedWebsites: z.array(z.string()).max(5).optional(),
- safeSearch: z.boolean().optional()
-})
-
-const xSourceSchema = z.object({
- type: z.literal('x'),
- xHandles: z.array(z.string()).optional()
-})
-
-const newsSourceSchema = z.object({
- type: z.literal('news'),
- country: z.string().length(2).optional(),
- excludedWebsites: z.array(z.string()).max(5).optional(),
- safeSearch: z.boolean().optional()
-})
-
-const rssSourceSchema = z.object({
- type: z.literal('rss'),
- links: z.array(z.url()).max(1) // currently only supports one RSS link
-})
-
-const searchSourceSchema = z.discriminatedUnion('type', [
- webSourceSchema,
- xSourceSchema,
- newsSourceSchema,
- rssSourceSchema
-])
-
-export const xaiProviderOptions = z.object({
- /**
- * reasoning effort for reasoning models
- * only supported by grok-3-mini and grok-3-mini-fast models
- */
- reasoningEffort: z.enum(['low', 'high']).optional(),
-
- searchParameters: z
- .object({
- /**
- * search mode preference
- * - "off": disables search completely
- * - "auto": model decides whether to search (default)
- * - "on": always enables search
- */
- mode: z.enum(['off', 'auto', 'on']),
-
- /**
- * whether to return citations in the response
- * defaults to true
- */
- returnCitations: z.boolean().optional(),
-
- /**
- * start date for search data (ISO8601 format: YYYY-MM-DD)
- */
- fromDate: z.string().optional(),
-
- /**
- * end date for search data (ISO8601 format: YYYY-MM-DD)
- */
- toDate: z.string().optional(),
-
- /**
- * maximum number of search results to consider
- * defaults to 20
- */
- maxSearchResults: z.number().min(1).max(50).optional(),
-
- /**
- * data sources to search from
- * defaults to ["web", "x"] if not specified
- */
- sources: z.array(searchSourceSchema).optional()
- })
- .optional()
-})
-
-export type XaiProviderOptions = z.infer
diff --git a/packages/aiCore/src/core/plugins/built-in/index.ts b/packages/aiCore/src/core/plugins/built-in/index.ts
index e7dcae8738..1f8916b09a 100644
--- a/packages/aiCore/src/core/plugins/built-in/index.ts
+++ b/packages/aiCore/src/core/plugins/built-in/index.ts
@@ -7,5 +7,9 @@ export const BUILT_IN_PLUGIN_PREFIX = 'built-in:'
export { googleToolsPlugin } from './googleToolsPlugin'
export { createLoggingPlugin } from './logging'
export { createPromptToolUsePlugin } from './toolUsePlugin/promptToolUsePlugin'
-export type { PromptToolUseConfig, ToolUseRequestContext, ToolUseResult } from './toolUsePlugin/type'
-export { webSearchPlugin } from './webSearchPlugin'
+export type {
+ PromptToolUseConfig,
+ ToolUseRequestContext,
+ ToolUseResult
+} from './toolUsePlugin/type'
+export { webSearchPlugin, type WebSearchPluginConfig } from './webSearchPlugin'
diff --git a/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/helper.ts b/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/helper.ts
index a7c7187bca..4845ce4ace 100644
--- a/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/helper.ts
+++ b/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/helper.ts
@@ -3,13 +3,16 @@ import { google } from '@ai-sdk/google'
import { openai } from '@ai-sdk/openai'
import { ProviderOptionsMap } from '../../../options/types'
+import { OpenRouterSearchConfig } from './openrouter'
/**
* 从 AI SDK 的工具函数中提取参数类型,以确保类型安全。
*/
-type OpenAISearchConfig = Parameters[0]
-type AnthropicSearchConfig = Parameters[0]
-type GoogleSearchConfig = Parameters[0]
+export type OpenAISearchConfig = NonNullable[0]>
+export type OpenAISearchPreviewConfig = NonNullable[0]>
+export type AnthropicSearchConfig = NonNullable[0]>
+export type GoogleSearchConfig = NonNullable[0]>
+export type XAISearchConfig = NonNullable
/**
* 插件初始化时接收的完整配置对象
@@ -18,10 +21,12 @@ type GoogleSearchConfig = Parameters[0]
*/
export interface WebSearchPluginConfig {
openai?: OpenAISearchConfig
+ 'openai-chat'?: OpenAISearchPreviewConfig
anthropic?: AnthropicSearchConfig
xai?: ProviderOptionsMap['xai']['searchParameters']
google?: GoogleSearchConfig
'google-vertex'?: GoogleSearchConfig
+ openrouter?: OpenRouterSearchConfig
}
/**
@@ -31,6 +36,7 @@ export const DEFAULT_WEB_SEARCH_CONFIG: WebSearchPluginConfig = {
google: {},
'google-vertex': {},
openai: {},
+ 'openai-chat': {},
xai: {
mode: 'on',
returnCitations: true,
@@ -39,6 +45,14 @@ export const DEFAULT_WEB_SEARCH_CONFIG: WebSearchPluginConfig = {
},
anthropic: {
maxUses: 5
+ },
+ openrouter: {
+ plugins: [
+ {
+ id: 'web',
+ max_results: 5
+ }
+ ]
}
}
diff --git a/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/index.ts b/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/index.ts
index d941e0d0c7..abd3ce3e2c 100644
--- a/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/index.ts
+++ b/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/index.ts
@@ -6,7 +6,7 @@ import { anthropic } from '@ai-sdk/anthropic'
import { google } from '@ai-sdk/google'
import { openai } from '@ai-sdk/openai'
-import { createXaiOptions, mergeProviderOptions } from '../../../options'
+import { createOpenRouterOptions, createXaiOptions, mergeProviderOptions } from '../../../options'
import { definePlugin } from '../../'
import type { AiRequestContext } from '../../types'
import { DEFAULT_WEB_SEARCH_CONFIG, WebSearchPluginConfig } from './helper'
@@ -31,6 +31,13 @@ export const webSearchPlugin = (config: WebSearchPluginConfig = DEFAULT_WEB_SEAR
}
break
}
+ case 'openai-chat': {
+ if (config['openai-chat']) {
+ if (!params.tools) params.tools = {}
+ params.tools.web_search_preview = openai.tools.webSearchPreview(config['openai-chat'])
+ }
+ break
+ }
case 'anthropic': {
if (config.anthropic) {
@@ -56,6 +63,14 @@ export const webSearchPlugin = (config: WebSearchPluginConfig = DEFAULT_WEB_SEAR
}
break
}
+
+ case 'openrouter': {
+ if (config.openrouter) {
+ const searchOptions = createOpenRouterOptions(config.openrouter)
+ params.providerOptions = mergeProviderOptions(params.providerOptions, searchOptions)
+ }
+ break
+ }
}
return params
diff --git a/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/openrouter.ts b/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/openrouter.ts
new file mode 100644
index 0000000000..ebf1e7bf9a
--- /dev/null
+++ b/packages/aiCore/src/core/plugins/built-in/webSearchPlugin/openrouter.ts
@@ -0,0 +1,26 @@
+export type OpenRouterSearchConfig = {
+ plugins?: Array<{
+ id: 'web'
+ /**
+ * Maximum number of search results to include (default: 5)
+ */
+ max_results?: number
+ /**
+ * Custom search prompt to guide the search query
+ */
+ search_prompt?: string
+ }>
+ /**
+ * Built-in web search options for models that support native web search
+ */
+ web_search_options?: {
+ /**
+ * Maximum number of search results to include
+ */
+ max_results?: number
+ /**
+ * Custom search prompt to guide the search query
+ */
+ search_prompt?: string
+ }
+}
diff --git a/packages/aiCore/src/core/providers/schemas.ts b/packages/aiCore/src/core/providers/schemas.ts
index e4b8d8aa64..83338cf057 100644
--- a/packages/aiCore/src/core/providers/schemas.ts
+++ b/packages/aiCore/src/core/providers/schemas.ts
@@ -9,7 +9,9 @@ import { createDeepSeek } from '@ai-sdk/deepseek'
import { createGoogleGenerativeAI } from '@ai-sdk/google'
import { createOpenAI, type OpenAIProviderSettings } from '@ai-sdk/openai'
import { createOpenAICompatible } from '@ai-sdk/openai-compatible'
+import { LanguageModelV2 } from '@ai-sdk/provider'
import { createXai } from '@ai-sdk/xai'
+import { createOpenRouter } from '@openrouter/ai-sdk-provider'
import { customProvider, Provider } from 'ai'
import { z } from 'zod'
@@ -25,7 +27,8 @@ export const baseProviderIds = [
'xai',
'azure',
'azure-responses',
- 'deepseek'
+ 'deepseek',
+ 'openrouter'
] as const
/**
@@ -38,10 +41,14 @@ export const baseProviderIdSchema = z.enum(baseProviderIds)
*/
export type BaseProviderId = z.infer
+export const isBaseProvider = (id: ProviderId): id is BaseProviderId => {
+ return baseProviderIdSchema.safeParse(id).success
+}
+
type BaseProvider = {
id: BaseProviderId
name: string
- creator: (options: any) => Provider
+ creator: (options: any) => Provider | LanguageModelV2
supportsImageGeneration: boolean
}
@@ -119,6 +126,12 @@ export const baseProviders = [
name: 'DeepSeek',
creator: createDeepSeek,
supportsImageGeneration: false
+ },
+ {
+ id: 'openrouter',
+ name: 'OpenRouter',
+ creator: createOpenRouter,
+ supportsImageGeneration: true
}
] as const satisfies BaseProvider[]
diff --git a/packages/shared/config/constant.ts b/packages/shared/config/constant.ts
index 18246cd1e7..3dc2a45a6a 100644
--- a/packages/shared/config/constant.ts
+++ b/packages/shared/config/constant.ts
@@ -216,5 +216,6 @@ export enum codeTools {
qwenCode = 'qwen-code',
claudeCode = 'claude-code',
geminiCli = 'gemini-cli',
- openaiCodex = 'openai-codex'
+ openaiCodex = 'openai-codex',
+ iFlowCli = 'iflow-cli'
}
diff --git a/src/main/services/CodeToolsService.ts b/src/main/services/CodeToolsService.ts
index 6e3bb19022..1372bf1f88 100644
--- a/src/main/services/CodeToolsService.ts
+++ b/src/main/services/CodeToolsService.ts
@@ -51,6 +51,8 @@ class CodeToolsService {
return '@openai/codex'
case codeTools.qwenCode:
return '@qwen-code/qwen-code'
+ case codeTools.iFlowCli:
+ return '@iflow-ai/iflow-cli'
default:
throw new Error(`Unsupported CLI tool: ${cliTool}`)
}
@@ -66,6 +68,8 @@ class CodeToolsService {
return 'codex'
case codeTools.qwenCode:
return 'qwen'
+ case codeTools.iFlowCli:
+ return 'iflow'
default:
throw new Error(`Unsupported CLI tool: ${cliTool}`)
}
diff --git a/src/renderer/src/aiCore/middleware/AiSdkMiddlewareBuilder.ts b/src/renderer/src/aiCore/middleware/AiSdkMiddlewareBuilder.ts
index f0d3b2eb59..eabdf1815f 100644
--- a/src/renderer/src/aiCore/middleware/AiSdkMiddlewareBuilder.ts
+++ b/src/renderer/src/aiCore/middleware/AiSdkMiddlewareBuilder.ts
@@ -1,3 +1,4 @@
+import { WebSearchPluginConfig } from '@cherrystudio/ai-core/built-in/plugins'
import { loggerService } from '@logger'
import type { MCPTool, Message, Model, Provider } from '@renderer/types'
import type { Chunk } from '@renderer/types/chunk'
@@ -26,6 +27,8 @@ export interface AiSdkMiddlewareConfig {
enableUrlContext: boolean
mcpTools?: MCPTool[]
uiMessages?: Message[]
+ // 内置搜索配置
+ webSearchPluginConfig?: WebSearchPluginConfig
}
/**
@@ -137,7 +140,7 @@ export function buildAiSdkMiddlewares(config: AiSdkMiddlewareConfig): LanguageMo
return builder.build()
}
-const tagNameArray = ['think', 'thought']
+const tagNameArray = ['think', 'thought', 'reasoning']
/**
* 添加provider特定的中间件
@@ -164,6 +167,16 @@ function addProviderSpecificMiddlewares(builder: AiSdkMiddlewareBuilder, config:
case 'gemini':
// Gemini特定中间件
break
+ case 'aws-bedrock': {
+ if (config.model?.id.includes('gpt-oss')) {
+ const tagName = tagNameArray[2]
+ builder.add({
+ name: 'thinking-tag-extraction',
+ middleware: extractReasoningMiddleware({ tagName })
+ })
+ }
+ break
+ }
default:
// 其他provider的通用处理
break
diff --git a/src/renderer/src/aiCore/plugins/PluginBuilder.ts b/src/renderer/src/aiCore/plugins/PluginBuilder.ts
index d94ed4aab9..7c5478eb77 100644
--- a/src/renderer/src/aiCore/plugins/PluginBuilder.ts
+++ b/src/renderer/src/aiCore/plugins/PluginBuilder.ts
@@ -30,9 +30,8 @@ export function buildPlugins(
}
// 1. 模型内置搜索
- if (middlewareConfig.enableWebSearch) {
- // 内置了默认搜索参数,如果改的话可以传config进去
- plugins.push(webSearchPlugin())
+ if (middlewareConfig.enableWebSearch && middlewareConfig.webSearchPluginConfig) {
+ plugins.push(webSearchPlugin(middlewareConfig.webSearchPluginConfig))
}
// 2. 支持工具调用时添加搜索插件
if (middlewareConfig.isSupportedToolUse || middlewareConfig.isPromptToolUse) {
diff --git a/src/renderer/src/aiCore/prepareParams/parameterBuilder.ts b/src/renderer/src/aiCore/prepareParams/parameterBuilder.ts
index 3f9e9ff071..0a89e73c62 100644
--- a/src/renderer/src/aiCore/prepareParams/parameterBuilder.ts
+++ b/src/renderer/src/aiCore/prepareParams/parameterBuilder.ts
@@ -5,6 +5,8 @@
import { vertexAnthropic } from '@ai-sdk/google-vertex/anthropic/edge'
import { vertex } from '@ai-sdk/google-vertex/edge'
+import { WebSearchPluginConfig } from '@cherrystudio/ai-core/built-in/plugins'
+import { isBaseProvider } from '@cherrystudio/ai-core/core/providers/schemas'
import { loggerService } from '@logger'
import {
isGenerateImageModel,
@@ -16,8 +18,11 @@ import {
isWebSearchModel
} from '@renderer/config/models'
import { getAssistantSettings, getDefaultModel } from '@renderer/services/AssistantService'
+import store from '@renderer/store'
+import { CherryWebSearchConfig } from '@renderer/store/websearch'
import { type Assistant, type MCPTool, type Provider } from '@renderer/types'
import type { StreamTextParams } from '@renderer/types/aiCoreTypes'
+import { mapRegexToPatterns } from '@renderer/utils/blacklistMatchPattern'
import type { ModelMessage, Tool } from 'ai'
import { stepCountIs } from 'ai'
@@ -25,6 +30,7 @@ import { getAiSdkProviderId } from '../provider/factory'
import { setupToolsConfig } from '../utils/mcp'
import { buildProviderOptions } from '../utils/options'
import { getAnthropicThinkingBudget } from '../utils/reasoning'
+import { buildProviderBuiltinWebSearchConfig } from '../utils/websearch'
import { getTemperature, getTopP } from './modelParameters'
const logger = loggerService.withContext('parameterBuilder')
@@ -42,6 +48,7 @@ export async function buildStreamTextParams(
options: {
mcpTools?: MCPTool[]
webSearchProviderId?: string
+ webSearchConfig?: CherryWebSearchConfig
requestOptions?: {
signal?: AbortSignal
timeout?: number
@@ -57,6 +64,7 @@ export async function buildStreamTextParams(
enableGenerateImage: boolean
enableUrlContext: boolean
}
+ webSearchPluginConfig?: WebSearchPluginConfig
}> {
const { mcpTools } = options
@@ -93,6 +101,12 @@ export async function buildStreamTextParams(
// }
// 构建真正的 providerOptions
+ const webSearchConfig: CherryWebSearchConfig = {
+ maxResults: store.getState().websearch.maxResults,
+ excludeDomains: store.getState().websearch.excludeDomains,
+ searchWithTime: store.getState().websearch.searchWithTime
+ }
+
const providerOptions = buildProviderOptions(assistant, model, provider, {
enableReasoning,
enableWebSearch,
@@ -109,15 +123,21 @@ export async function buildStreamTextParams(
maxTokens -= getAnthropicThinkingBudget(assistant, model)
}
- // google-vertex | google-vertex-anthropic
+ let webSearchPluginConfig: WebSearchPluginConfig | undefined = undefined
if (enableWebSearch) {
+ if (isBaseProvider(aiSdkProviderId)) {
+ webSearchPluginConfig = buildProviderBuiltinWebSearchConfig(aiSdkProviderId, webSearchConfig)
+ }
if (!tools) {
tools = {}
}
if (aiSdkProviderId === 'google-vertex') {
tools.google_search = vertex.tools.googleSearch({}) as ProviderDefinedTool
} else if (aiSdkProviderId === 'google-vertex-anthropic') {
- tools.web_search = vertexAnthropic.tools.webSearch_20250305({}) as ProviderDefinedTool
+ tools.web_search = vertexAnthropic.tools.webSearch_20250305({
+ maxUses: webSearchConfig.maxResults,
+ blockedDomains: mapRegexToPatterns(webSearchConfig.excludeDomains)
+ }) as ProviderDefinedTool
}
}
@@ -151,7 +171,8 @@ export async function buildStreamTextParams(
return {
params,
modelId: model.id,
- capabilities: { enableReasoning, enableWebSearch, enableGenerateImage, enableUrlContext }
+ capabilities: { enableReasoning, enableWebSearch, enableGenerateImage, enableUrlContext },
+ webSearchPluginConfig
}
}
diff --git a/src/renderer/src/aiCore/provider/factory.ts b/src/renderer/src/aiCore/provider/factory.ts
index 617758753e..bfcd3da383 100644
--- a/src/renderer/src/aiCore/provider/factory.ts
+++ b/src/renderer/src/aiCore/provider/factory.ts
@@ -69,6 +69,9 @@ export function getAiSdkProviderId(provider: Provider): ProviderId | 'openai-com
return resolvedFromType
}
}
+ if (provider.apiHost.includes('api.openai.com')) {
+ return 'openai-chat'
+ }
// 3. 最后的fallback(通常会成为openai-compatible)
return provider.id as ProviderId
}
diff --git a/src/renderer/src/aiCore/utils/options.ts b/src/renderer/src/aiCore/utils/options.ts
index f85c8c7879..dec475fc8b 100644
--- a/src/renderer/src/aiCore/utils/options.ts
+++ b/src/renderer/src/aiCore/utils/options.ts
@@ -82,6 +82,7 @@ export function buildProviderOptions(
// 应该覆盖所有类型
switch (baseProviderId) {
case 'openai':
+ case 'openai-chat':
case 'azure':
providerSpecificOptions = {
...buildOpenAIProviderOptions(assistant, model, capabilities),
@@ -101,13 +102,15 @@ export function buildProviderOptions(
providerSpecificOptions = buildXAIProviderOptions(assistant, model, capabilities)
break
case 'deepseek':
- case 'openai-compatible':
+ case 'openrouter':
+ case 'openai-compatible': {
// 对于其他 provider,使用通用的构建逻辑
providerSpecificOptions = {
...buildGenericProviderOptions(assistant, model, capabilities),
serviceTier: serviceTierSetting
}
break
+ }
default:
throw new Error(`Unsupported base provider ${baseProviderId}`)
}
diff --git a/src/renderer/src/aiCore/utils/reasoning.ts b/src/renderer/src/aiCore/utils/reasoning.ts
index 385d8183c5..bee07b1e0d 100644
--- a/src/renderer/src/aiCore/utils/reasoning.ts
+++ b/src/renderer/src/aiCore/utils/reasoning.ts
@@ -312,7 +312,7 @@ export function getOpenAIReasoningParams(assistant: Assistant, model: Model): Re
export function getAnthropicThinkingBudget(assistant: Assistant, model: Model): number {
const { maxTokens, reasoning_effort: reasoningEffort } = getAssistantSettings(assistant)
- if (maxTokens === undefined || reasoningEffort === undefined) {
+ if (reasoningEffort === undefined) {
return 0
}
const effortRatio = EFFORT_RATIO[reasoningEffort]
diff --git a/src/renderer/src/aiCore/utils/websearch.ts b/src/renderer/src/aiCore/utils/websearch.ts
index d2d0345826..e95f3e60cf 100644
--- a/src/renderer/src/aiCore/utils/websearch.ts
+++ b/src/renderer/src/aiCore/utils/websearch.ts
@@ -1,6 +1,13 @@
+import {
+ AnthropicSearchConfig,
+ OpenAISearchConfig,
+ WebSearchPluginConfig
+} from '@cherrystudio/ai-core/core/plugins/built-in/webSearchPlugin/helper'
+import { BaseProviderId } from '@cherrystudio/ai-core/provider'
import { isOpenAIWebSearchChatCompletionOnlyModel } from '@renderer/config/models'
-import { WEB_SEARCH_PROMPT_FOR_OPENROUTER } from '@renderer/config/prompts'
+import { CherryWebSearchConfig } from '@renderer/store/websearch'
import { Model } from '@renderer/types'
+import { mapRegexToPatterns } from '@renderer/utils/blacklistMatchPattern'
export function getWebSearchParams(model: Model): Record {
if (model.provider === 'hunyuan') {
@@ -21,11 +28,78 @@ export function getWebSearchParams(model: Model): Record {
web_search_options: {}
}
}
-
- if (model.provider === 'openrouter') {
- return {
- plugins: [{ id: 'web', search_prompts: WEB_SEARCH_PROMPT_FOR_OPENROUTER }]
- }
- }
return {}
}
+
+/**
+ * range in [0, 100]
+ * @param maxResults
+ */
+function mapMaxResultToOpenAIContextSize(maxResults: number): OpenAISearchConfig['searchContextSize'] {
+ if (maxResults <= 33) return 'low'
+ if (maxResults <= 66) return 'medium'
+ return 'high'
+}
+
+export function buildProviderBuiltinWebSearchConfig(
+ providerId: BaseProviderId,
+ webSearchConfig: CherryWebSearchConfig
+): WebSearchPluginConfig {
+ switch (providerId) {
+ case 'openai': {
+ return {
+ openai: {
+ searchContextSize: mapMaxResultToOpenAIContextSize(webSearchConfig.maxResults)
+ }
+ }
+ }
+ case 'openai-chat': {
+ return {
+ 'openai-chat': {
+ searchContextSize: mapMaxResultToOpenAIContextSize(webSearchConfig.maxResults)
+ }
+ }
+ }
+ case 'anthropic': {
+ const anthropicSearchOptions: AnthropicSearchConfig = {
+ maxUses: webSearchConfig.maxResults,
+ blockedDomains: mapRegexToPatterns(webSearchConfig.excludeDomains)
+ }
+ return {
+ anthropic: anthropicSearchOptions
+ }
+ }
+ case 'xai': {
+ return {
+ xai: {
+ maxSearchResults: webSearchConfig.maxResults,
+ returnCitations: true,
+ sources: [
+ {
+ type: 'web',
+ excludedWebsites: mapRegexToPatterns(webSearchConfig.excludeDomains)
+ },
+ { type: 'news' },
+ { type: 'x' }
+ ],
+ mode: 'on'
+ }
+ }
+ }
+ case 'openrouter': {
+ return {
+ openrouter: {
+ plugins: [
+ {
+ id: 'web',
+ max_results: webSearchConfig.maxResults
+ }
+ ]
+ }
+ }
+ }
+ default: {
+ throw new Error(`Unsupported provider: ${providerId}`)
+ }
+ }
+}
diff --git a/src/renderer/src/config/models/utils.ts b/src/renderer/src/config/models/utils.ts
index 3fd27308f8..39078e2924 100644
--- a/src/renderer/src/config/models/utils.ts
+++ b/src/renderer/src/config/models/utils.ts
@@ -229,6 +229,11 @@ export const isGPT5SeriesModel = (model: Model) => {
return modelId.includes('gpt-5')
}
+export const isGPT5SeriesReasoningModel = (model: Model) => {
+ const modelId = getLowerBaseModelName(model.id)
+ return modelId.includes('gpt-5') && !modelId.includes('chat')
+}
+
export const isGeminiModel = (model: Model) => {
const modelId = getLowerBaseModelName(model.id)
return modelId.includes('gemini')
diff --git a/src/renderer/src/config/providers.ts b/src/renderer/src/config/providers.ts
index f28a88c7c7..a710605b64 100644
--- a/src/renderer/src/config/providers.ts
+++ b/src/renderer/src/config/providers.ts
@@ -1020,7 +1020,7 @@ export const PROVIDER_URLS: Record = {
},
anthropic: {
api: {
- url: 'https://api.anthropic.com/'
+ url: 'https://api.anthropic.com'
},
websites: {
official: 'https://anthropic.com/',
diff --git a/src/renderer/src/hooks/useAppInit.ts b/src/renderer/src/hooks/useAppInit.ts
index 571e5877a8..e9e3b55706 100644
--- a/src/renderer/src/hooks/useAppInit.ts
+++ b/src/renderer/src/hooks/useAppInit.ts
@@ -38,7 +38,7 @@ export function useAppInit() {
customCss,
enableDataCollection
} = useSettings()
- const { isTopNavbar } = useNavbarPosition()
+ const { isLeftNavbar } = useNavbarPosition()
const { minappShow } = useRuntime()
const { setDefaultModel, setQuickModel, setTranslateModel } = useDefaultModel()
const avatar = useLiveQuery(() => db.settings.get('image://avatar'))
@@ -102,16 +102,15 @@ export function useAppInit() {
}, [language])
useEffect(() => {
- const transparentWindow = windowStyle === 'transparent' && isMac && !minappShow
+ const isMacTransparentWindow = windowStyle === 'transparent' && isMac
- if (minappShow && isTopNavbar) {
- window.root.style.background =
- windowStyle === 'transparent' && isMac ? 'var(--color-background)' : 'var(--navbar-background)'
+ if (minappShow && isLeftNavbar) {
+ window.root.style.background = isMacTransparentWindow ? 'var(--color-background)' : 'var(--navbar-background)'
return
}
- window.root.style.background = transparentWindow ? 'var(--navbar-background-mac)' : 'var(--navbar-background)'
- }, [windowStyle, minappShow, theme, isTopNavbar])
+ window.root.style.background = isMacTransparentWindow ? 'var(--navbar-background-mac)' : 'var(--navbar-background)'
+ }, [windowStyle, minappShow, theme, isLeftNavbar])
useEffect(() => {
if (isLocalAi) {
diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json
index 57da145599..5dfa5fcda2 100644
--- a/src/renderer/src/i18n/locales/en-us.json
+++ b/src/renderer/src/i18n/locales/en-us.json
@@ -679,7 +679,12 @@
"title": "Topics",
"unpin": "Unpin Topic"
},
- "translate": "Translate"
+ "translate": "Translate",
+ "web_search": {
+ "warning": {
+ "openai": "The GPT-5 model's minimal reasoning effort does not support web search."
+ }
+ }
},
"code": {
"auto_update_to_latest": "Automatically update to latest version",
diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json
index 21329ea42b..a15732fdfa 100644
--- a/src/renderer/src/i18n/locales/zh-cn.json
+++ b/src/renderer/src/i18n/locales/zh-cn.json
@@ -679,7 +679,12 @@
"title": "话题",
"unpin": "取消固定"
},
- "translate": "翻译"
+ "translate": "翻译",
+ "web_search": {
+ "warning": {
+ "openai": "GPT5 模型 minimal 思考强度不支持网络搜索"
+ }
+ }
},
"code": {
"auto_update_to_latest": "检查更新并安装最新版本",
diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json
index 771c64f66c..bfffe15ef2 100644
--- a/src/renderer/src/i18n/locales/zh-tw.json
+++ b/src/renderer/src/i18n/locales/zh-tw.json
@@ -679,7 +679,12 @@
"title": "話題",
"unpin": "取消固定"
},
- "translate": "翻譯"
+ "translate": "翻譯",
+ "web_search": {
+ "warning": {
+ "openai": "GPT-5 模型的最小推理力度不支援網路搜尋。"
+ }
+ }
},
"code": {
"auto_update_to_latest": "檢查更新並安裝最新版本",
diff --git a/src/renderer/src/i18n/translate/el-gr.json b/src/renderer/src/i18n/translate/el-gr.json
index eab721a437..d1d65cc1b3 100644
--- a/src/renderer/src/i18n/translate/el-gr.json
+++ b/src/renderer/src/i18n/translate/el-gr.json
@@ -381,8 +381,9 @@
"translate": "Μετάφραση στο {{target_language}}",
"translating": "Μετάφραση...",
"upload": {
+ "attachment": "Μεταφόρτωση συνημμένου",
"document": "Φόρτωση έγγραφου (το μοντέλο δεν υποστηρίζει εικόνες)",
- "label": "Φόρτωση εικόνας ή έγγραφου",
+ "image_or_document": "Μεταφόρτωση εικόνας ή εγγράφου",
"upload_from_local": "Μεταφόρτωση αρχείου από τον υπολογιστή..."
},
"url_context": "Περιεχόμενο ιστοσελίδας",
@@ -678,7 +679,12 @@
"title": "Θέματα",
"unpin": "Ξεκαρφίτσωμα"
},
- "translate": "Μετάφραση"
+ "translate": "Μετάφραση",
+ "web_search": {
+ "warning": {
+ "openai": "Το μοντέλο GPT5 με ελάχιστη ένταση σκέψης δεν υποστηρίζει αναζήτηση στο διαδίκτυο"
+ }
+ }
},
"code": {
"auto_update_to_latest": "Έλεγχος για ενημερώσεις και εγκατάσταση της τελευταίας έκδοσης",
diff --git a/src/renderer/src/i18n/translate/es-es.json b/src/renderer/src/i18n/translate/es-es.json
index f76498899c..3a9f92032f 100644
--- a/src/renderer/src/i18n/translate/es-es.json
+++ b/src/renderer/src/i18n/translate/es-es.json
@@ -381,8 +381,9 @@
"translate": "Traducir a {{target_language}}",
"translating": "Traduciendo...",
"upload": {
+ "attachment": "Subir archivo adjunto",
"document": "Subir documento (el modelo no admite imágenes)",
- "label": "Subir imagen o documento",
+ "image_or_document": "Subir imagen o documento",
"upload_from_local": "Subir archivo local..."
},
"url_context": "Contexto de la página web",
@@ -678,7 +679,12 @@
"title": "Tema",
"unpin": "Quitar fijación"
},
- "translate": "Traducir"
+ "translate": "Traducir",
+ "web_search": {
+ "warning": {
+ "openai": "El modelo GPT5 con intensidad de pensamiento mínima no admite búsqueda en la web."
+ }
+ }
},
"code": {
"auto_update_to_latest": "Comprobar actualizaciones e instalar la versión más reciente",
diff --git a/src/renderer/src/i18n/translate/fr-fr.json b/src/renderer/src/i18n/translate/fr-fr.json
index 59cc1e0bac..7180059c76 100644
--- a/src/renderer/src/i18n/translate/fr-fr.json
+++ b/src/renderer/src/i18n/translate/fr-fr.json
@@ -381,8 +381,9 @@
"translate": "Traduire en {{target_language}}",
"translating": "Traduction en cours...",
"upload": {
+ "attachment": "Télécharger la pièce jointe",
"document": "Télécharger un document (le modèle ne prend pas en charge les images)",
- "label": "Télécharger une image ou un document",
+ "image_or_document": "Télécharger une image ou un document",
"upload_from_local": "Télécharger un fichier local..."
},
"url_context": "Contexte de la page web",
@@ -678,7 +679,12 @@
"title": "Sujet",
"unpin": "Annuler le fixage"
},
- "translate": "Traduire"
+ "translate": "Traduire",
+ "web_search": {
+ "warning": {
+ "openai": "Le modèle GPT5 avec une intensité de réflexion minimale ne prend pas en charge la recherche sur Internet."
+ }
+ }
},
"code": {
"auto_update_to_latest": "Vérifier les mises à jour et installer la dernière version",
diff --git a/src/renderer/src/i18n/translate/ja-jp.json b/src/renderer/src/i18n/translate/ja-jp.json
index b28177319f..204e7aa713 100644
--- a/src/renderer/src/i18n/translate/ja-jp.json
+++ b/src/renderer/src/i18n/translate/ja-jp.json
@@ -381,8 +381,9 @@
"translate": "{{target_language}}に翻訳",
"translating": "翻訳中...",
"upload": {
+ "attachment": "添付ファイルをアップロード",
"document": "ドキュメントをアップロード(モデルは画像をサポートしません)",
- "label": "画像またはドキュメントをアップロード",
+ "image_or_document": "画像またはドキュメントをアップロード",
"upload_from_local": "ローカルファイルをアップロード..."
},
"url_context": "URLコンテキスト",
@@ -678,7 +679,12 @@
"title": "トピック",
"unpin": "固定解除"
},
- "translate": "翻訳"
+ "translate": "翻訳",
+ "web_search": {
+ "warning": {
+ "openai": "GPT5モデルの最小思考強度ではネット検索はサポートされません"
+ }
+ }
},
"code": {
"auto_update_to_latest": "最新バージョンを自動的に更新する",
diff --git a/src/renderer/src/i18n/translate/pt-pt.json b/src/renderer/src/i18n/translate/pt-pt.json
index 7d6f4cafbb..a188200139 100644
--- a/src/renderer/src/i18n/translate/pt-pt.json
+++ b/src/renderer/src/i18n/translate/pt-pt.json
@@ -381,8 +381,9 @@
"translate": "Traduzir para {{target_language}}",
"translating": "Traduzindo...",
"upload": {
+ "attachment": "Carregar anexo",
"document": "Carregar documento (o modelo não suporta imagens)",
- "label": "Carregar imagem ou documento",
+ "image_or_document": "Carregar imagem ou documento",
"upload_from_local": "Fazer upload de arquivo local..."
},
"url_context": "Contexto da Página da Web",
@@ -678,7 +679,12 @@
"title": "Tópicos",
"unpin": "Desfixar"
},
- "translate": "Traduzir"
+ "translate": "Traduzir",
+ "web_search": {
+ "warning": {
+ "openai": "O modelo GPT5 com intensidade mínima de pensamento não suporta pesquisa na web"
+ }
+ }
},
"code": {
"auto_update_to_latest": "Verificar atualizações e instalar a versão mais recente",
diff --git a/src/renderer/src/i18n/translate/ru-ru.json b/src/renderer/src/i18n/translate/ru-ru.json
index 78285665d6..aa94c67f9a 100644
--- a/src/renderer/src/i18n/translate/ru-ru.json
+++ b/src/renderer/src/i18n/translate/ru-ru.json
@@ -381,8 +381,9 @@
"translate": "Перевести на {{target_language}}",
"translating": "Перевод...",
"upload": {
+ "attachment": "Загрузить вложение",
"document": "Загрузить документ (модель не поддерживает изображения)",
- "label": "Загрузить изображение или документ",
+ "image_or_document": "Загрузить изображение или документ",
"upload_from_local": "Загрузить локальный файл..."
},
"url_context": "Контекст страницы",
@@ -678,7 +679,12 @@
"title": "Топики",
"unpin": "Открепленные темы"
},
- "translate": "Перевести"
+ "translate": "Перевести",
+ "web_search": {
+ "warning": {
+ "openai": "Модель GPT5 с минимальной интенсивностью мышления не поддерживает поиск в интернете"
+ }
+ }
},
"code": {
"auto_update_to_latest": "Автоматически обновлять до последней версии",
diff --git a/src/renderer/src/pages/code/index.ts b/src/renderer/src/pages/code/index.ts
index 4cbcd56040..f24003a1c4 100644
--- a/src/renderer/src/pages/code/index.ts
+++ b/src/renderer/src/pages/code/index.ts
@@ -19,7 +19,8 @@ export const CLI_TOOLS = [
{ value: codeTools.claudeCode, label: 'Claude Code' },
{ value: codeTools.qwenCode, label: 'Qwen Code' },
{ value: codeTools.geminiCli, label: 'Gemini CLI' },
- { value: codeTools.openaiCodex, label: 'OpenAI Codex' }
+ { value: codeTools.openaiCodex, label: 'OpenAI Codex' },
+ { value: codeTools.iFlowCli, label: 'iFlow CLI' }
]
export const GEMINI_SUPPORTED_PROVIDERS = ['aihubmix', 'dmxapi', 'new-api']
@@ -35,7 +36,8 @@ export const CLI_TOOL_PROVIDER_MAP: Record Pr
providers.filter((p) => p.type === 'gemini' || GEMINI_SUPPORTED_PROVIDERS.includes(p.id)),
[codeTools.qwenCode]: (providers) => providers.filter((p) => p.type.includes('openai')),
[codeTools.openaiCodex]: (providers) =>
- providers.filter((p) => p.id === 'openai' || OPENAI_CODEX_SUPPORTED_PROVIDERS.includes(p.id))
+ providers.filter((p) => p.id === 'openai' || OPENAI_CODEX_SUPPORTED_PROVIDERS.includes(p.id)),
+ [codeTools.iFlowCli]: (providers) => providers.filter((p) => p.type.includes('openai'))
}
export const getCodeToolsApiBaseUrl = (model: Model, type: EndpointType) => {
@@ -144,6 +146,12 @@ export const generateToolEnvironment = ({
env.OPENAI_MODEL = model.id
env.OPENAI_MODEL_PROVIDER = modelProvider.id
break
+
+ case codeTools.iFlowCli:
+ env.IFLOW_API_KEY = apiKey
+ env.IFLOW_BASE_URL = baseUrl
+ env.IFLOW_MODEL_NAME = model.id
+ break
}
return env
diff --git a/src/renderer/src/pages/home/Chat.tsx b/src/renderer/src/pages/home/Chat.tsx
index 4ea6bcdd57..d6d7f08d90 100644
--- a/src/renderer/src/pages/home/Chat.tsx
+++ b/src/renderer/src/pages/home/Chat.tsx
@@ -155,23 +155,23 @@ const Chat: FC = (props) => {
flex={1}
justify="space-between"
style={{ maxWidth: chatMaxWidth, height: mainHeight }}>
-
- }
- filter={contentSearchFilter}
- includeUser={filterIncludeUser}
- onIncludeUserChange={userOutlinedItemClickHandler}
- />
- {messageNavigation === 'buttons' && }
+
+ }
+ filter={contentSearchFilter}
+ includeUser={filterIncludeUser}
+ onIncludeUserChange={userOutlinedItemClickHandler}
+ />
+ {messageNavigation === 'buttons' && }
{isMultiSelectMode && }
diff --git a/src/renderer/src/pages/home/Inputbar/Inputbar.tsx b/src/renderer/src/pages/home/Inputbar/Inputbar.tsx
index 864ea71a21..9a130e45ff 100644
--- a/src/renderer/src/pages/home/Inputbar/Inputbar.tsx
+++ b/src/renderer/src/pages/home/Inputbar/Inputbar.tsx
@@ -71,6 +71,7 @@ interface Props {
let _text = ''
let _files: FileType[] = []
+let _mentionedModelsCache: Model[] = []
const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) => {
const [text, setText] = useState(_text)
@@ -103,7 +104,8 @@ const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) =
const spaceClickTimer = useRef(null)
const [isTranslating, setIsTranslating] = useState(false)
const [selectedKnowledgeBases, setSelectedKnowledgeBases] = useState([])
- const [mentionedModels, setMentionedModels] = useState([])
+ const [mentionedModels, setMentionedModels] = useState(_mentionedModelsCache)
+ const mentionedModelsRef = useRef(mentionedModels)
const [isDragging, setIsDragging] = useState(false)
const [isFileDragging, setIsFileDragging] = useState(false)
const [textareaHeight, setTextareaHeight] = useState()
@@ -114,6 +116,10 @@ const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) =
const isGenerateImageAssistant = useMemo(() => isGenerateImageModel(model), [model])
const { setTimeoutTimer } = useTimer()
+ useEffect(() => {
+ mentionedModelsRef.current = mentionedModels
+ }, [mentionedModels])
+
const isVisionSupported = useMemo(
() =>
(mentionedModels.length > 0 && isVisionModels(mentionedModels)) ||
@@ -179,6 +185,13 @@ const Inputbar: FC = ({ assistant: _assistant, setActiveTopic, topic }) =
_text = text
_files = files
+ useEffect(() => {
+ // 利用useEffect清理函数在卸载组件时更新状态缓存
+ return () => {
+ _mentionedModelsCache = mentionedModelsRef.current
+ }
+ }, [])
+
const focusTextarea = useCallback(() => {
textareaRef.current?.focus()
}, [])
diff --git a/src/renderer/src/pages/home/Inputbar/ThinkingButton.tsx b/src/renderer/src/pages/home/Inputbar/ThinkingButton.tsx
index 5ee0c628c8..7e2b7edd38 100644
--- a/src/renderer/src/pages/home/Inputbar/ThinkingButton.tsx
+++ b/src/renderer/src/pages/home/Inputbar/ThinkingButton.tsx
@@ -8,7 +8,13 @@ import {
MdiLightbulbOn80
} from '@renderer/components/Icons/SVGIcon'
import { QuickPanelReservedSymbol, useQuickPanel } from '@renderer/components/QuickPanel'
-import { getThinkModelType, isDoubaoThinkingAutoModel, MODEL_SUPPORTED_OPTIONS } from '@renderer/config/models'
+import {
+ getThinkModelType,
+ isDoubaoThinkingAutoModel,
+ isGPT5SeriesReasoningModel,
+ isOpenAIWebSearchModel,
+ MODEL_SUPPORTED_OPTIONS
+} from '@renderer/config/models'
import { useAssistant } from '@renderer/hooks/useAssistant'
import { getReasoningEffortOptionsLabel } from '@renderer/i18n/label'
import { Model, ThinkingOption } from '@renderer/types'
@@ -61,6 +67,15 @@ const ThinkingButton: FC = ({ ref, model, assistantId }): ReactElement =>
})
return
}
+ if (
+ isOpenAIWebSearchModel(model) &&
+ isGPT5SeriesReasoningModel(model) &&
+ assistant.enableWebSearch &&
+ option === 'minimal'
+ ) {
+ window.toast.warning(t('chat.web_search.warning.openai'))
+ return
+ }
updateAssistantSettings({
reasoning_effort: option,
reasoning_effort_cache: option,
@@ -68,7 +83,7 @@ const ThinkingButton: FC = ({ ref, model, assistantId }): ReactElement =>
})
return
},
- [updateAssistantSettings]
+ [updateAssistantSettings, assistant.enableWebSearch, model, t]
)
const panelItems = useMemo(() => {
diff --git a/src/renderer/src/pages/home/Inputbar/WebSearchButton.tsx b/src/renderer/src/pages/home/Inputbar/WebSearchButton.tsx
index cb3c5fb6d9..807781bac4 100644
--- a/src/renderer/src/pages/home/Inputbar/WebSearchButton.tsx
+++ b/src/renderer/src/pages/home/Inputbar/WebSearchButton.tsx
@@ -3,7 +3,12 @@ import { loggerService } from '@logger'
import { ActionIconButton } from '@renderer/components/Buttons'
import { BingLogo, BochaLogo, ExaLogo, SearXNGLogo, TavilyLogo, ZhipuLogo } from '@renderer/components/Icons'
import { QuickPanelListItem, QuickPanelReservedSymbol, useQuickPanel } from '@renderer/components/QuickPanel'
-import { isGeminiModel, isWebSearchModel } from '@renderer/config/models'
+import {
+ isGeminiModel,
+ isGPT5SeriesReasoningModel,
+ isOpenAIWebSearchModel,
+ isWebSearchModel
+} from '@renderer/config/models'
import { isGeminiWebSearchProvider } from '@renderer/config/providers'
import { useAssistant } from '@renderer/hooks/useAssistant'
import { useTimer } from '@renderer/hooks/useTimer'
@@ -115,6 +120,15 @@ const WebSearchButton: FC = ({ ref, assistantId }) => {
update.enableWebSearch = false
window.toast.warning(t('chat.mcp.warning.gemini_web_search'))
}
+ if (
+ isOpenAIWebSearchModel(model) &&
+ isGPT5SeriesReasoningModel(model) &&
+ update.enableWebSearch &&
+ assistant.settings?.reasoning_effort === 'minimal'
+ ) {
+ update.enableWebSearch = false
+ window.toast.warning(t('chat.web_search.warning.openai'))
+ }
setTimeoutTimer('updateSelectedWebSearchBuiltin', () => updateAssistant(update), 200)
}, [assistant, setTimeoutTimer, t, updateAssistant])
diff --git a/src/renderer/src/pages/settings/ProviderSettings/ProviderSetting.tsx b/src/renderer/src/pages/settings/ProviderSettings/ProviderSetting.tsx
index 0bd7b152f4..68bfc67ba2 100644
--- a/src/renderer/src/pages/settings/ProviderSettings/ProviderSetting.tsx
+++ b/src/renderer/src/pages/settings/ProviderSettings/ProviderSetting.tsx
@@ -16,7 +16,13 @@ import { useAppDispatch } from '@renderer/store'
import { updateWebSearchProvider } from '@renderer/store/websearch'
import { isSystemProvider } from '@renderer/types'
import { ApiKeyConnectivity, HealthStatus } from '@renderer/types/healthCheck'
-import { formatApiHost, formatApiKeys, getFancyProviderName, isOpenAIProvider } from '@renderer/utils'
+import {
+ formatApiHost,
+ formatApiKeys,
+ getFancyProviderName,
+ isAnthropicProvider,
+ isOpenAIProvider
+} from '@renderer/utils'
import { formatErrorMessage } from '@renderer/utils/error'
import { Button, Divider, Flex, Input, Select, Space, Switch, Tooltip } from 'antd'
import Link from 'antd/es/typography/Link'
@@ -212,6 +218,10 @@ const ProviderSetting: FC = ({ providerId }) => {
if (provider.type === 'azure-openai') {
return formatApiHost(apiHost) + 'openai/v1'
}
+
+ if (provider.type === 'anthropic') {
+ return formatApiHost(apiHost) + 'messages'
+ }
return formatApiHost(apiHost) + 'responses'
}
@@ -361,7 +371,7 @@ const ProviderSetting: FC = ({ providerId }) => {
)}
- {isOpenAIProvider(provider) && (
+ {(isOpenAIProvider(provider) || isAnthropicProvider(provider)) && (
diff --git a/src/renderer/src/services/ApiService.ts b/src/renderer/src/services/ApiService.ts
index 01807027ba..d954fc1f85 100644
--- a/src/renderer/src/services/ApiService.ts
+++ b/src/renderer/src/services/ApiService.ts
@@ -117,7 +117,8 @@ export async function fetchChatCompletion({
const {
params: aiSdkParams,
modelId,
- capabilities
+ capabilities,
+ webSearchPluginConfig
} = await buildStreamTextParams(messages, assistant, provider, {
mcpTools: mcpTools,
webSearchProviderId: assistant.webSearchProviderId,
@@ -132,6 +133,7 @@ export async function fetchChatCompletion({
isPromptToolUse: isPromptToolUse(assistant),
isSupportedToolUse: isSupportedToolUse(assistant),
isImageGenerationEndpoint: isDedicatedImageGenerationModel(assistant.model || getDefaultModel()),
+ webSearchPluginConfig: webSearchPluginConfig,
enableWebSearch: capabilities.enableWebSearch,
enableGenerateImage: capabilities.enableGenerateImage,
enableUrlContext: capabilities.enableUrlContext,
diff --git a/src/renderer/src/store/index.ts b/src/renderer/src/store/index.ts
index dc599d0658..3b3cfa3f0c 100644
--- a/src/renderer/src/store/index.ts
+++ b/src/renderer/src/store/index.ts
@@ -67,7 +67,7 @@ const persistedReducer = persistReducer(
{
key: 'cherry-studio',
storage,
- version: 155,
+ version: 156,
blacklist: ['runtime', 'messages', 'messageBlocks', 'tabs'],
migrate
},
diff --git a/src/renderer/src/store/migrate.ts b/src/renderer/src/store/migrate.ts
index f58059337b..f9b187606c 100644
--- a/src/renderer/src/store/migrate.ts
+++ b/src/renderer/src/store/migrate.ts
@@ -2485,6 +2485,21 @@ const migrateConfig = {
logger.error('migrate 155 error', error as Error)
return state
}
+ },
+ '156': (state: RootState) => {
+ try {
+ state.llm.providers.forEach((provider) => {
+ if (provider.id === SystemProviderIds.anthropic) {
+ if (provider.apiHost.endsWith('/')) {
+ provider.apiHost = provider.apiHost.slice(0, -1)
+ }
+ }
+ })
+ return state
+ } catch (error) {
+ logger.error('migrate 156 error', error as Error)
+ return state
+ }
}
}
diff --git a/src/renderer/src/store/websearch.ts b/src/renderer/src/store/websearch.ts
index 1e3fe2a25b..16029ccf47 100644
--- a/src/renderer/src/store/websearch.ts
+++ b/src/renderer/src/store/websearch.ts
@@ -41,6 +41,8 @@ export interface WebSearchState {
providerConfig: Record
}
+export type CherryWebSearchConfig = Pick
+
export const initialState: WebSearchState = {
defaultProvider: 'local-bing',
providers: WEB_SEARCH_PROVIDERS,
diff --git a/src/renderer/src/utils/__tests__/blacklistMatchPattern.test.ts b/src/renderer/src/utils/__tests__/blacklistMatchPattern.test.ts
index 4656e30562..a5c0983479 100644
--- a/src/renderer/src/utils/__tests__/blacklistMatchPattern.test.ts
+++ b/src/renderer/src/utils/__tests__/blacklistMatchPattern.test.ts
@@ -26,7 +26,7 @@
import { describe, expect, it } from 'vitest'
-import { MatchPatternMap } from '../blacklistMatchPattern'
+import { mapRegexToPatterns, MatchPatternMap } from '../blacklistMatchPattern'
function get(map: MatchPatternMap, url: string) {
return map.get(url).sort()
@@ -161,3 +161,28 @@ describe('blacklistMatchPattern', () => {
expect(get(map, 'https://b.mozilla.org/path/')).toEqual([0, 1, 2, 6])
})
})
+
+describe('mapRegexToPatterns', () => {
+ it('extracts domains from regex patterns', () => {
+ const result = mapRegexToPatterns([
+ '/example\\.com/',
+ '/(?:www\\.)?sub\\.example\\.co\\.uk/',
+ '/api\\.service\\.io/',
+ 'https://baidu.com'
+ ])
+
+ expect(result).toEqual(['example.com', 'sub.example.co.uk', 'api.service.io', 'baidu.com'])
+ })
+
+ it('deduplicates domains across multiple patterns', () => {
+ const result = mapRegexToPatterns(['/example\\.com/', '/(example\\.com|test\\.org)/'])
+
+ expect(result).toEqual(['example.com', 'test.org'])
+ })
+
+ it('ignores patterns without domain matches', () => {
+ const result = mapRegexToPatterns(['', 'plain-domain.com', '/^https?:\\/\\/[^/]+$/'])
+
+ expect(result).toEqual(['plain-domain.com'])
+ })
+})
diff --git a/src/renderer/src/utils/blacklistMatchPattern.ts b/src/renderer/src/utils/blacklistMatchPattern.ts
index 9e78ab58fb..b00e07a785 100644
--- a/src/renderer/src/utils/blacklistMatchPattern.ts
+++ b/src/renderer/src/utils/blacklistMatchPattern.ts
@@ -202,6 +202,43 @@ export async function parseSubscribeContent(url: string): Promise {
throw error
}
}
+
+export function mapRegexToPatterns(patterns: string[]): string[] {
+ const patternSet = new Set()
+ const domainMatcher = /[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+/g
+
+ patterns.forEach((pattern) => {
+ if (!pattern) {
+ return
+ }
+
+ // Handle regex patterns (wrapped in /)
+ if (pattern.startsWith('/') && pattern.endsWith('/')) {
+ const rawPattern = pattern.slice(1, -1)
+ const normalizedPattern = rawPattern.replace(/\\\./g, '.').replace(/\\\//g, '/')
+ const matches = normalizedPattern.match(domainMatcher)
+
+ if (matches) {
+ matches.forEach((match) => {
+ patternSet.add(match.replace(/http(s)?:\/\//g, '').toLowerCase())
+ })
+ }
+ } else if (pattern.includes('://')) {
+ // Handle URLs with protocol (e.g., https://baidu.com)
+ const matches = pattern.match(domainMatcher)
+ if (matches) {
+ matches.forEach((match) => {
+ patternSet.add(match.replace(/http(s)?:\/\//g, '').toLowerCase())
+ })
+ }
+ } else {
+ patternSet.add(pattern.toLowerCase())
+ }
+ })
+
+ return Array.from(patternSet)
+}
+
export async function filterResultWithBlacklist(
response: WebSearchProviderResponse,
websearch: WebSearchState
diff --git a/src/renderer/src/utils/index.ts b/src/renderer/src/utils/index.ts
index 828d288ba8..64f943946a 100644
--- a/src/renderer/src/utils/index.ts
+++ b/src/renderer/src/utils/index.ts
@@ -205,6 +205,10 @@ export function isOpenAIProvider(provider: Provider): boolean {
return !['anthropic', 'gemini', 'vertexai'].includes(provider.type)
}
+export function isAnthropicProvider(provider: Provider): boolean {
+ return provider.type === 'anthropic'
+}
+
/**
* 判断模型是否为用户手动选择
* @param {Model} model 模型对象
diff --git a/src/renderer/src/windows/mini/MiniWindowApp.tsx b/src/renderer/src/windows/mini/MiniWindowApp.tsx
index b459a3e027..0f6d8bc60d 100644
--- a/src/renderer/src/windows/mini/MiniWindowApp.tsx
+++ b/src/renderer/src/windows/mini/MiniWindowApp.tsx
@@ -1,9 +1,9 @@
import '@renderer/databases'
-import { HeroUIProvider } from '@heroui/react'
import { ErrorBoundary } from '@renderer/components/ErrorBoundary'
import { ToastPortal } from '@renderer/components/ToastPortal'
import { getToastUtilities } from '@renderer/components/TopView/toast'
+import { HeroUIProvider } from '@renderer/context/HeroUIProvider'
import { useSettings } from '@renderer/hooks/useSettings'
import store, { persistor } from '@renderer/store'
import { useEffect } from 'react'
diff --git a/src/renderer/src/windows/selection/action/entryPoint.tsx b/src/renderer/src/windows/selection/action/entryPoint.tsx
index 44f24ccb97..5aa8d3f745 100644
--- a/src/renderer/src/windows/selection/action/entryPoint.tsx
+++ b/src/renderer/src/windows/selection/action/entryPoint.tsx
@@ -2,13 +2,13 @@ import '@renderer/assets/styles/index.css'
import '@renderer/assets/styles/tailwind.css'
import '@ant-design/v5-patch-for-react-19'
-import { HeroUIProvider } from '@heroui/react'
import KeyvStorage from '@kangfenmao/keyv-storage'
import { loggerService } from '@logger'
import { ToastPortal } from '@renderer/components/ToastPortal'
import { getToastUtilities } from '@renderer/components/TopView/toast'
import AntdProvider from '@renderer/context/AntdProvider'
import { CodeStyleProvider } from '@renderer/context/CodeStyleProvider'
+import { HeroUIProvider } from '@renderer/context/HeroUIProvider'
import { ThemeProvider } from '@renderer/context/ThemeProvider'
import storeSyncService from '@renderer/services/StoreSyncService'
import store, { persistor } from '@renderer/store'
diff --git a/yarn.lock b/yarn.lock
index a012104817..9eeca22a16 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -386,8 +386,8 @@ __metadata:
linkType: hard
"@anthropic-ai/claude-code@npm:^1.0.113":
- version: 1.0.113
- resolution: "@anthropic-ai/claude-code@npm:1.0.113"
+ version: 1.0.118
+ resolution: "@anthropic-ai/claude-code@npm:1.0.118"
dependencies:
"@img/sharp-darwin-arm64": "npm:^0.33.5"
"@img/sharp-darwin-x64": "npm:^0.33.5"
@@ -410,7 +410,7 @@ __metadata:
optional: true
bin:
claude: cli.js
- checksum: 10c0/954303e43916a221b0ea9185844621957ac0d42835be654a0f66f09e01a06ef0d121e98bf156c8a51a30d65ca75d2002e5ece561a960cfcc618467a79fb21cba
+ checksum: 10c0/90e9feac857bfcbdaa3797c70cccfad8588ed45bc9ea6c88664e2f08fa71d069cfb28ce17c20a67ddd841d9a8c7a50e61281687975f7d5ebde9b39f63551cefb
languageName: node
linkType: hard
@@ -2338,7 +2338,7 @@ __metadata:
languageName: node
linkType: hard
-"@cherrystudio/ai-core@workspace:^1.0.0-alpha.16, @cherrystudio/ai-core@workspace:packages/aiCore":
+"@cherrystudio/ai-core@workspace:^1.0.0-alpha.18, @cherrystudio/ai-core@workspace:packages/aiCore":
version: 0.0.0-use.local
resolution: "@cherrystudio/ai-core@workspace:packages/aiCore"
dependencies:
@@ -3449,16 +3449,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/aix-ppc64@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/aix-ppc64@npm:0.25.8"
+"@esbuild/aix-ppc64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/aix-ppc64@npm:0.25.10"
conditions: os=aix & cpu=ppc64
languageName: node
linkType: hard
-"@esbuild/aix-ppc64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/aix-ppc64@npm:0.25.9"
+"@esbuild/aix-ppc64@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/aix-ppc64@npm:0.25.8"
conditions: os=aix & cpu=ppc64
languageName: node
linkType: hard
@@ -3470,16 +3470,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/android-arm64@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/android-arm64@npm:0.25.8"
+"@esbuild/android-arm64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/android-arm64@npm:0.25.10"
conditions: os=android & cpu=arm64
languageName: node
linkType: hard
-"@esbuild/android-arm64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/android-arm64@npm:0.25.9"
+"@esbuild/android-arm64@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/android-arm64@npm:0.25.8"
conditions: os=android & cpu=arm64
languageName: node
linkType: hard
@@ -3491,16 +3491,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/android-arm@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/android-arm@npm:0.25.8"
+"@esbuild/android-arm@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/android-arm@npm:0.25.10"
conditions: os=android & cpu=arm
languageName: node
linkType: hard
-"@esbuild/android-arm@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/android-arm@npm:0.25.9"
+"@esbuild/android-arm@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/android-arm@npm:0.25.8"
conditions: os=android & cpu=arm
languageName: node
linkType: hard
@@ -3512,16 +3512,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/android-x64@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/android-x64@npm:0.25.8"
+"@esbuild/android-x64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/android-x64@npm:0.25.10"
conditions: os=android & cpu=x64
languageName: node
linkType: hard
-"@esbuild/android-x64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/android-x64@npm:0.25.9"
+"@esbuild/android-x64@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/android-x64@npm:0.25.8"
conditions: os=android & cpu=x64
languageName: node
linkType: hard
@@ -3533,16 +3533,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/darwin-arm64@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/darwin-arm64@npm:0.25.8"
+"@esbuild/darwin-arm64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/darwin-arm64@npm:0.25.10"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
-"@esbuild/darwin-arm64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/darwin-arm64@npm:0.25.9"
+"@esbuild/darwin-arm64@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/darwin-arm64@npm:0.25.8"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
@@ -3554,16 +3554,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/darwin-x64@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/darwin-x64@npm:0.25.8"
+"@esbuild/darwin-x64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/darwin-x64@npm:0.25.10"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
-"@esbuild/darwin-x64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/darwin-x64@npm:0.25.9"
+"@esbuild/darwin-x64@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/darwin-x64@npm:0.25.8"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
@@ -3575,16 +3575,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/freebsd-arm64@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/freebsd-arm64@npm:0.25.8"
+"@esbuild/freebsd-arm64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/freebsd-arm64@npm:0.25.10"
conditions: os=freebsd & cpu=arm64
languageName: node
linkType: hard
-"@esbuild/freebsd-arm64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/freebsd-arm64@npm:0.25.9"
+"@esbuild/freebsd-arm64@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/freebsd-arm64@npm:0.25.8"
conditions: os=freebsd & cpu=arm64
languageName: node
linkType: hard
@@ -3596,16 +3596,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/freebsd-x64@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/freebsd-x64@npm:0.25.8"
+"@esbuild/freebsd-x64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/freebsd-x64@npm:0.25.10"
conditions: os=freebsd & cpu=x64
languageName: node
linkType: hard
-"@esbuild/freebsd-x64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/freebsd-x64@npm:0.25.9"
+"@esbuild/freebsd-x64@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/freebsd-x64@npm:0.25.8"
conditions: os=freebsd & cpu=x64
languageName: node
linkType: hard
@@ -3617,16 +3617,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/linux-arm64@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/linux-arm64@npm:0.25.8"
+"@esbuild/linux-arm64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/linux-arm64@npm:0.25.10"
conditions: os=linux & cpu=arm64
languageName: node
linkType: hard
-"@esbuild/linux-arm64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/linux-arm64@npm:0.25.9"
+"@esbuild/linux-arm64@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/linux-arm64@npm:0.25.8"
conditions: os=linux & cpu=arm64
languageName: node
linkType: hard
@@ -3638,16 +3638,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/linux-arm@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/linux-arm@npm:0.25.8"
+"@esbuild/linux-arm@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/linux-arm@npm:0.25.10"
conditions: os=linux & cpu=arm
languageName: node
linkType: hard
-"@esbuild/linux-arm@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/linux-arm@npm:0.25.9"
+"@esbuild/linux-arm@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/linux-arm@npm:0.25.8"
conditions: os=linux & cpu=arm
languageName: node
linkType: hard
@@ -3659,16 +3659,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/linux-ia32@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/linux-ia32@npm:0.25.8"
+"@esbuild/linux-ia32@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/linux-ia32@npm:0.25.10"
conditions: os=linux & cpu=ia32
languageName: node
linkType: hard
-"@esbuild/linux-ia32@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/linux-ia32@npm:0.25.9"
+"@esbuild/linux-ia32@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/linux-ia32@npm:0.25.8"
conditions: os=linux & cpu=ia32
languageName: node
linkType: hard
@@ -3680,16 +3680,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/linux-loong64@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/linux-loong64@npm:0.25.8"
+"@esbuild/linux-loong64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/linux-loong64@npm:0.25.10"
conditions: os=linux & cpu=loong64
languageName: node
linkType: hard
-"@esbuild/linux-loong64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/linux-loong64@npm:0.25.9"
+"@esbuild/linux-loong64@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/linux-loong64@npm:0.25.8"
conditions: os=linux & cpu=loong64
languageName: node
linkType: hard
@@ -3701,16 +3701,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/linux-mips64el@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/linux-mips64el@npm:0.25.8"
+"@esbuild/linux-mips64el@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/linux-mips64el@npm:0.25.10"
conditions: os=linux & cpu=mips64el
languageName: node
linkType: hard
-"@esbuild/linux-mips64el@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/linux-mips64el@npm:0.25.9"
+"@esbuild/linux-mips64el@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/linux-mips64el@npm:0.25.8"
conditions: os=linux & cpu=mips64el
languageName: node
linkType: hard
@@ -3722,16 +3722,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/linux-ppc64@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/linux-ppc64@npm:0.25.8"
+"@esbuild/linux-ppc64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/linux-ppc64@npm:0.25.10"
conditions: os=linux & cpu=ppc64
languageName: node
linkType: hard
-"@esbuild/linux-ppc64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/linux-ppc64@npm:0.25.9"
+"@esbuild/linux-ppc64@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/linux-ppc64@npm:0.25.8"
conditions: os=linux & cpu=ppc64
languageName: node
linkType: hard
@@ -3743,16 +3743,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/linux-riscv64@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/linux-riscv64@npm:0.25.8"
+"@esbuild/linux-riscv64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/linux-riscv64@npm:0.25.10"
conditions: os=linux & cpu=riscv64
languageName: node
linkType: hard
-"@esbuild/linux-riscv64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/linux-riscv64@npm:0.25.9"
+"@esbuild/linux-riscv64@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/linux-riscv64@npm:0.25.8"
conditions: os=linux & cpu=riscv64
languageName: node
linkType: hard
@@ -3764,16 +3764,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/linux-s390x@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/linux-s390x@npm:0.25.8"
+"@esbuild/linux-s390x@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/linux-s390x@npm:0.25.10"
conditions: os=linux & cpu=s390x
languageName: node
linkType: hard
-"@esbuild/linux-s390x@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/linux-s390x@npm:0.25.9"
+"@esbuild/linux-s390x@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/linux-s390x@npm:0.25.8"
conditions: os=linux & cpu=s390x
languageName: node
linkType: hard
@@ -3785,6 +3785,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/linux-x64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/linux-x64@npm:0.25.10"
+ conditions: os=linux & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/linux-x64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/linux-x64@npm:0.25.8"
@@ -3792,10 +3799,10 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/linux-x64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/linux-x64@npm:0.25.9"
- conditions: os=linux & cpu=x64
+"@esbuild/netbsd-arm64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/netbsd-arm64@npm:0.25.10"
+ conditions: os=netbsd & cpu=arm64
languageName: node
linkType: hard
@@ -3806,13 +3813,6 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/netbsd-arm64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/netbsd-arm64@npm:0.25.9"
- conditions: os=netbsd & cpu=arm64
- languageName: node
- linkType: hard
-
"@esbuild/netbsd-x64@npm:0.18.20":
version: 0.18.20
resolution: "@esbuild/netbsd-x64@npm:0.18.20"
@@ -3820,6 +3820,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/netbsd-x64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/netbsd-x64@npm:0.25.10"
+ conditions: os=netbsd & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/netbsd-x64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/netbsd-x64@npm:0.25.8"
@@ -3827,10 +3834,10 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/netbsd-x64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/netbsd-x64@npm:0.25.9"
- conditions: os=netbsd & cpu=x64
+"@esbuild/openbsd-arm64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/openbsd-arm64@npm:0.25.10"
+ conditions: os=openbsd & cpu=arm64
languageName: node
linkType: hard
@@ -3841,13 +3848,6 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/openbsd-arm64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/openbsd-arm64@npm:0.25.9"
- conditions: os=openbsd & cpu=arm64
- languageName: node
- linkType: hard
-
"@esbuild/openbsd-x64@npm:0.18.20":
version: 0.18.20
resolution: "@esbuild/openbsd-x64@npm:0.18.20"
@@ -3855,6 +3855,13 @@ __metadata:
languageName: node
linkType: hard
+"@esbuild/openbsd-x64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/openbsd-x64@npm:0.25.10"
+ conditions: os=openbsd & cpu=x64
+ languageName: node
+ linkType: hard
+
"@esbuild/openbsd-x64@npm:0.25.8":
version: 0.25.8
resolution: "@esbuild/openbsd-x64@npm:0.25.8"
@@ -3862,10 +3869,10 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/openbsd-x64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/openbsd-x64@npm:0.25.9"
- conditions: os=openbsd & cpu=x64
+"@esbuild/openharmony-arm64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/openharmony-arm64@npm:0.25.10"
+ conditions: os=openharmony & cpu=arm64
languageName: node
linkType: hard
@@ -3876,13 +3883,6 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/openharmony-arm64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/openharmony-arm64@npm:0.25.9"
- conditions: os=openharmony & cpu=arm64
- languageName: node
- linkType: hard
-
"@esbuild/sunos-x64@npm:0.18.20":
version: 0.18.20
resolution: "@esbuild/sunos-x64@npm:0.18.20"
@@ -3890,16 +3890,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/sunos-x64@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/sunos-x64@npm:0.25.8"
+"@esbuild/sunos-x64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/sunos-x64@npm:0.25.10"
conditions: os=sunos & cpu=x64
languageName: node
linkType: hard
-"@esbuild/sunos-x64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/sunos-x64@npm:0.25.9"
+"@esbuild/sunos-x64@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/sunos-x64@npm:0.25.8"
conditions: os=sunos & cpu=x64
languageName: node
linkType: hard
@@ -3911,16 +3911,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/win32-arm64@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/win32-arm64@npm:0.25.8"
+"@esbuild/win32-arm64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/win32-arm64@npm:0.25.10"
conditions: os=win32 & cpu=arm64
languageName: node
linkType: hard
-"@esbuild/win32-arm64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/win32-arm64@npm:0.25.9"
+"@esbuild/win32-arm64@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/win32-arm64@npm:0.25.8"
conditions: os=win32 & cpu=arm64
languageName: node
linkType: hard
@@ -3932,16 +3932,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/win32-ia32@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/win32-ia32@npm:0.25.8"
+"@esbuild/win32-ia32@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/win32-ia32@npm:0.25.10"
conditions: os=win32 & cpu=ia32
languageName: node
linkType: hard
-"@esbuild/win32-ia32@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/win32-ia32@npm:0.25.9"
+"@esbuild/win32-ia32@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/win32-ia32@npm:0.25.8"
conditions: os=win32 & cpu=ia32
languageName: node
linkType: hard
@@ -3953,16 +3953,16 @@ __metadata:
languageName: node
linkType: hard
-"@esbuild/win32-x64@npm:0.25.8":
- version: 0.25.8
- resolution: "@esbuild/win32-x64@npm:0.25.8"
+"@esbuild/win32-x64@npm:0.25.10":
+ version: 0.25.10
+ resolution: "@esbuild/win32-x64@npm:0.25.10"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
-"@esbuild/win32-x64@npm:0.25.9":
- version: 0.25.9
- resolution: "@esbuild/win32-x64@npm:0.25.9"
+"@esbuild/win32-x64@npm:0.25.8":
+ version: 0.25.8
+ resolution: "@esbuild/win32-x64@npm:0.25.8"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
@@ -14169,7 +14169,7 @@ __metadata:
"@aws-sdk/client-bedrock-runtime": "npm:^3.840.0"
"@aws-sdk/client-s3": "npm:^3.840.0"
"@biomejs/biome": "npm:2.2.4"
- "@cherrystudio/ai-core": "workspace:^1.0.0-alpha.16"
+ "@cherrystudio/ai-core": "workspace:^1.0.0-alpha.18"
"@cherrystudio/embedjs": "npm:^0.1.31"
"@cherrystudio/embedjs-libsql": "npm:^0.1.31"
"@cherrystudio/embedjs-loader-csv": "npm:^0.1.31"
@@ -14304,7 +14304,6 @@ __metadata:
diff: "npm:^8.0.2"
docx: "npm:^9.0.2"
dompurify: "npm:^3.2.6"
- dotenv: "npm:^17.2.2"
dotenv-cli: "npm:^7.4.2"
drizzle-kit: "npm:^0.31.4"
drizzle-orm: "npm:^0.44.5"
@@ -14417,7 +14416,7 @@ __metadata:
turndown: "npm:7.2.0"
turndown-plugin-gfm: "npm:^1.0.2"
tw-animate-css: "npm:^1.3.8"
- typescript: "npm:^5.6.2"
+ typescript: "npm:~5.8.2"
undici: "npm:6.21.2"
unified: "npm:^11.0.5"
uuid: "npm:^13.0.0"
@@ -17656,13 +17655,6 @@ __metadata:
languageName: node
linkType: hard
-"dotenv@npm:^17.2.2":
- version: 17.2.2
- resolution: "dotenv@npm:17.2.2"
- checksum: 10c0/be66513504590aff6eccb14167625aed9bd42ce80547f4fe5d195860211971a7060949b57108dfaeaf90658f79e40edccd3f233f0a978bff507b5b1565ae162b
- languageName: node
- linkType: hard
-
"drizzle-kit@npm:^0.31.4":
version: 0.31.4
resolution: "drizzle-kit@npm:0.31.4"
@@ -18193,35 +18185,35 @@ __metadata:
linkType: hard
"esbuild@npm:^0.25.4":
- version: 0.25.9
- resolution: "esbuild@npm:0.25.9"
+ version: 0.25.10
+ resolution: "esbuild@npm:0.25.10"
dependencies:
- "@esbuild/aix-ppc64": "npm:0.25.9"
- "@esbuild/android-arm": "npm:0.25.9"
- "@esbuild/android-arm64": "npm:0.25.9"
- "@esbuild/android-x64": "npm:0.25.9"
- "@esbuild/darwin-arm64": "npm:0.25.9"
- "@esbuild/darwin-x64": "npm:0.25.9"
- "@esbuild/freebsd-arm64": "npm:0.25.9"
- "@esbuild/freebsd-x64": "npm:0.25.9"
- "@esbuild/linux-arm": "npm:0.25.9"
- "@esbuild/linux-arm64": "npm:0.25.9"
- "@esbuild/linux-ia32": "npm:0.25.9"
- "@esbuild/linux-loong64": "npm:0.25.9"
- "@esbuild/linux-mips64el": "npm:0.25.9"
- "@esbuild/linux-ppc64": "npm:0.25.9"
- "@esbuild/linux-riscv64": "npm:0.25.9"
- "@esbuild/linux-s390x": "npm:0.25.9"
- "@esbuild/linux-x64": "npm:0.25.9"
- "@esbuild/netbsd-arm64": "npm:0.25.9"
- "@esbuild/netbsd-x64": "npm:0.25.9"
- "@esbuild/openbsd-arm64": "npm:0.25.9"
- "@esbuild/openbsd-x64": "npm:0.25.9"
- "@esbuild/openharmony-arm64": "npm:0.25.9"
- "@esbuild/sunos-x64": "npm:0.25.9"
- "@esbuild/win32-arm64": "npm:0.25.9"
- "@esbuild/win32-ia32": "npm:0.25.9"
- "@esbuild/win32-x64": "npm:0.25.9"
+ "@esbuild/aix-ppc64": "npm:0.25.10"
+ "@esbuild/android-arm": "npm:0.25.10"
+ "@esbuild/android-arm64": "npm:0.25.10"
+ "@esbuild/android-x64": "npm:0.25.10"
+ "@esbuild/darwin-arm64": "npm:0.25.10"
+ "@esbuild/darwin-x64": "npm:0.25.10"
+ "@esbuild/freebsd-arm64": "npm:0.25.10"
+ "@esbuild/freebsd-x64": "npm:0.25.10"
+ "@esbuild/linux-arm": "npm:0.25.10"
+ "@esbuild/linux-arm64": "npm:0.25.10"
+ "@esbuild/linux-ia32": "npm:0.25.10"
+ "@esbuild/linux-loong64": "npm:0.25.10"
+ "@esbuild/linux-mips64el": "npm:0.25.10"
+ "@esbuild/linux-ppc64": "npm:0.25.10"
+ "@esbuild/linux-riscv64": "npm:0.25.10"
+ "@esbuild/linux-s390x": "npm:0.25.10"
+ "@esbuild/linux-x64": "npm:0.25.10"
+ "@esbuild/netbsd-arm64": "npm:0.25.10"
+ "@esbuild/netbsd-x64": "npm:0.25.10"
+ "@esbuild/openbsd-arm64": "npm:0.25.10"
+ "@esbuild/openbsd-x64": "npm:0.25.10"
+ "@esbuild/openharmony-arm64": "npm:0.25.10"
+ "@esbuild/sunos-x64": "npm:0.25.10"
+ "@esbuild/win32-arm64": "npm:0.25.10"
+ "@esbuild/win32-ia32": "npm:0.25.10"
+ "@esbuild/win32-x64": "npm:0.25.10"
dependenciesMeta:
"@esbuild/aix-ppc64":
optional: true
@@ -18277,7 +18269,7 @@ __metadata:
optional: true
bin:
esbuild: bin/esbuild
- checksum: 10c0/aaa1284c75fcf45c82f9a1a117fe8dc5c45628e3386bda7d64916ae27730910b51c5aec7dd45a6ba19256be30ba2935e64a8f011a3f0539833071e06bf76d5b3
+ checksum: 10c0/8ee5fdd43ed0d4092ce7f41577c63147f54049d5617763f0549c638bbe939e8adaa8f1a2728adb63417eb11df51956b7b0d8eb88ee08c27ad1d42960256158fa
languageName: node
linkType: hard
@@ -29191,7 +29183,7 @@ __metadata:
languageName: node
linkType: hard
-"typescript@npm:^5.4.3, typescript@npm:^5.6.2":
+"typescript@npm:^5.4.3, typescript@npm:~5.8.2":
version: 5.8.3
resolution: "typescript@npm:5.8.3"
bin:
@@ -29211,7 +29203,7 @@ __metadata:
languageName: node
linkType: hard
-"typescript@patch:typescript@npm%3A^5.4.3#optional!builtin, typescript@patch:typescript@npm%3A^5.6.2#optional!builtin":
+"typescript@patch:typescript@npm%3A^5.4.3#optional!builtin, typescript@patch:typescript@npm%3A~5.8.2#optional!builtin":
version: 5.8.3
resolution: "typescript@patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5"
bin: