build: replace openai package with @cherrystudio/openai fork

Update all imports from 'openai' to '@cherrystudio/openai' across the codebase
Remove openai patch from package.json and add @cherrystudio/openai dependency
This commit is contained in:
icarus 2025-10-11 19:11:37 +08:00
parent 1c53222582
commit 05ad98bb20
31 changed files with 73 additions and 45 deletions

Binary file not shown.

View File

@ -124,6 +124,7 @@
"@cherrystudio/embedjs-ollama": "^0.1.31",
"@cherrystudio/embedjs-openai": "^0.1.31",
"@cherrystudio/extension-table-plus": "workspace:^",
"@cherrystudio/openai": "6.3.0-fork.1",
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/modifiers": "^9.0.0",
"@dnd-kit/sortable": "^10.0.0",
@ -294,7 +295,6 @@
"motion": "^12.10.5",
"notion-helper": "^1.3.22",
"npx-scope-finder": "^1.2.0",
"openai": "patch:openai@npm%3A5.12.2#~/.yarn/patches/openai-npm-5.12.2-30b075401c.patch",
"oxlint": "^1.15.0",
"oxlint-tsgolint": "^0.2.0",
"p-queue": "^8.1.0",

View File

@ -2,9 +2,9 @@
* baseLocale以外的文本[to be translated]
*
*/
import OpenAI from '@cherrystudio/openai'
import cliProgress from 'cli-progress'
import * as fs from 'fs'
import OpenAI from 'openai'
import * as path from 'path'
const localesDir = path.join(__dirname, '../src/renderer/src/i18n/locales')

View File

@ -4,9 +4,9 @@
* API_KEY=sk-xxxx BASE_URL=xxxx MODEL=xxxx ts-node scripts/update-i18n.ts
*/
import OpenAI from '@cherrystudio/openai'
import cliProgress from 'cli-progress'
import fs from 'fs'
import OpenAI from 'openai'
type I18NValue = string | { [key: string]: I18NValue }
type I18N = { [key: string]: I18NValue }

View File

@ -1,5 +1,5 @@
import { ChatCompletionCreateParams } from '@cherrystudio/openai/resources'
import express, { Request, Response } from 'express'
import { ChatCompletionCreateParams } from 'openai/resources'
import { loggerService } from '../../services/LoggerService'
import {

View File

@ -1,6 +1,6 @@
import OpenAI from '@cherrystudio/openai'
import { ChatCompletionCreateParams, ChatCompletionCreateParamsStreaming } from '@cherrystudio/openai/resources'
import { Provider } from '@types'
import OpenAI from 'openai'
import { ChatCompletionCreateParams, ChatCompletionCreateParamsStreaming } from 'openai/resources'
import { loggerService } from '../../services/LoggerService'
import { ModelValidationError, validateModelId } from '../utils'

View File

@ -1,8 +1,8 @@
import OpenAI from '@cherrystudio/openai'
import { loggerService } from '@logger'
import { fileStorage } from '@main/services/FileStorage'
import { FileListResponse, FileMetadata, FileUploadResponse, Provider } from '@types'
import * as fs from 'fs'
import OpenAI from 'openai'
import { CacheService } from '../CacheService'
import { BaseFileService } from './BaseFileService'

View File

@ -1,6 +1,6 @@
import OpenAI from '@cherrystudio/openai'
import { Provider } from '@renderer/types'
import { OpenAISdkParams, OpenAISdkRawOutput } from '@renderer/types/sdk'
import OpenAI from 'openai'
import { OpenAIAPIClient } from '../openai/OpenAIApiClient'

View File

@ -1,3 +1,9 @@
import OpenAI, { AzureOpenAI } from '@cherrystudio/openai'
import {
ChatCompletionContentPart,
ChatCompletionContentPartRefusal,
ChatCompletionTool
} from '@cherrystudio/openai/resources'
import { loggerService } from '@logger'
import { DEFAULT_MAX_TOKENS } from '@renderer/config/constant'
import {
@ -78,8 +84,6 @@ import {
} from '@renderer/utils/mcp-tools'
import { findFileBlocks, findImageBlocks } from '@renderer/utils/messageUtils/find'
import { t } from 'i18next'
import OpenAI, { AzureOpenAI } from 'openai'
import { ChatCompletionContentPart, ChatCompletionContentPartRefusal, ChatCompletionTool } from 'openai/resources'
import { GenericChunk } from '../../middleware/schemas'
import { RequestTransformer, ResponseChunkTransformer, ResponseChunkTransformerContext } from '../types'

View File

@ -1,3 +1,4 @@
import OpenAI, { AzureOpenAI } from '@cherrystudio/openai'
import { loggerService } from '@logger'
import {
isClaudeReasoningModel,
@ -24,7 +25,6 @@ import {
ReasoningEffortOptionalParams
} from '@renderer/types/sdk'
import { formatApiHost } from '@renderer/utils/api'
import OpenAI, { AzureOpenAI } from 'openai'
import { BaseApiClient } from '../BaseApiClient'

View File

@ -1,3 +1,5 @@
import OpenAI, { AzureOpenAI } from '@cherrystudio/openai'
import { ResponseInput } from '@cherrystudio/openai/resources/responses/responses'
import { loggerService } from '@logger'
import { GenericChunk } from '@renderer/aiCore/legacy/middleware/schemas'
import { CompletionsContext } from '@renderer/aiCore/legacy/middleware/types'
@ -46,8 +48,6 @@ import { findFileBlocks, findImageBlocks } from '@renderer/utils/messageUtils/fi
import { MB } from '@shared/config/constant'
import { t } from 'i18next'
import { isEmpty } from 'lodash'
import OpenAI, { AzureOpenAI } from 'openai'
import { ResponseInput } from 'openai/resources/responses/responses'
import { RequestTransformer, ResponseChunkTransformer } from '../types'
import { OpenAIAPIClient } from './OpenAIApiClient'
@ -349,7 +349,14 @@ export class OpenAIResponseAPIClient extends OpenAIBaseClient<
}
switch (message.type) {
case 'function_call_output':
sum += estimateTextTokens(message.output)
if (typeof message.output === 'string') {
sum += estimateTextTokens(message.output)
} else {
sum += message.output
.filter((item) => item.type === 'input_text')
.map((item) => estimateTextTokens(item.text))
.reduce((prev, cur) => prev + cur, 0)
}
break
case 'function_call':
sum += estimateTextTokens(message.arguments)

View File

@ -1,7 +1,7 @@
import OpenAI from '@cherrystudio/openai'
import { loggerService } from '@logger'
import { isSupportedModel } from '@renderer/config/models'
import { objectKeys, Provider } from '@renderer/types'
import OpenAI from 'openai'
import { OpenAIAPIClient } from '../openai/OpenAIApiClient'

View File

@ -1,7 +1,7 @@
import OpenAI from '@cherrystudio/openai'
import { loggerService } from '@logger'
import { isSupportedModel } from '@renderer/config/models'
import { Model, Provider } from '@renderer/types'
import OpenAI from 'openai'
import { OpenAIAPIClient } from '../openai/OpenAIApiClient'

View File

@ -1,4 +1,5 @@
import Anthropic from '@anthropic-ai/sdk'
import OpenAI from '@cherrystudio/openai'
import { Assistant, MCPTool, MCPToolResponse, Model, ToolCallResponse } from '@renderer/types'
import { Provider } from '@renderer/types'
import {
@ -13,7 +14,6 @@ import {
SdkTool,
SdkToolCall
} from '@renderer/types/sdk'
import OpenAI from 'openai'
import { CompletionsParams, GenericChunk } from '../middleware/schemas'
import { CompletionsContext } from '../middleware/types'

View File

@ -1,7 +1,7 @@
import OpenAI from '@cherrystudio/openai'
import { loggerService } from '@logger'
import { Provider } from '@renderer/types'
import { GenerateImageParams } from '@renderer/types'
import OpenAI from 'openai'
import { OpenAIAPIClient } from '../openai/OpenAIApiClient'

View File

@ -1,10 +1,10 @@
import OpenAI from '@cherrystudio/openai'
import { toFile } from '@cherrystudio/openai/uploads'
import { isDedicatedImageGenerationModel } from '@renderer/config/models'
import FileManager from '@renderer/services/FileManager'
import { ChunkType } from '@renderer/types/chunk'
import { findImageBlocks, getMainTextContent } from '@renderer/utils/messageUtils/find'
import { defaultTimeout } from '@shared/config/constant'
import OpenAI from 'openai'
import { toFile } from 'openai/uploads'
import { BaseApiClient } from '../../clients/BaseApiClient'
import { CompletionsParams, CompletionsResult, GenericChunk } from '../schemas'

View File

@ -3,6 +3,7 @@
*
*/
import type OpenAI from '@cherrystudio/openai'
import { loggerService } from '@logger'
import { getProviderByModel } from '@renderer/services/AssistantService'
import type { FileMetadata, Message, Model } from '@renderer/types'
@ -10,7 +11,6 @@ import { FileTypes } from '@renderer/types'
import { FileMessageBlock } from '@renderer/types/newMessage'
import { findFileBlocks } from '@renderer/utils/messageUtils/find'
import type { FilePart, TextPart } from 'ai'
import type OpenAI from 'openai'
import { getAiSdkProviderId } from '../provider/factory'
import { getFileSizeLimit, supportsImageInput, supportsLargeFileUpload, supportsPdfInput } from './modelCapabilities'

View File

@ -1,6 +1,6 @@
import OpenAI from '@cherrystudio/openai'
import { Model } from '@renderer/types'
import { getLowerBaseModelName } from '@renderer/utils'
import OpenAI from 'openai'
import { WEB_SEARCH_PROMPT_FOR_OPENROUTER } from '../prompts'
import { getWebSearchTools } from '../tools'

View File

@ -1,5 +1,5 @@
import { ChatCompletionTool } from '@cherrystudio/openai/resources'
import { Model } from '@renderer/types'
import { ChatCompletionTool } from 'openai/resources'
import { WEB_SEARCH_PROMPT_FOR_ZHIPU } from './prompts'

View File

@ -1,6 +1,6 @@
import { ChatCompletionContentPart, ChatCompletionMessageParam } from '@cherrystudio/openai/resources'
import { Model } from '@renderer/types'
import { findLast } from 'lodash'
import { ChatCompletionContentPart, ChatCompletionMessageParam } from 'openai/resources'
export function processReqMessages(
model: Model,

View File

@ -1,4 +1,5 @@
import { MessageStream } from '@anthropic-ai/sdk/resources/messages/messages'
import { Stream } from '@cherrystudio/openai/streaming'
import { loggerService } from '@logger'
import { SpanEntity, TokenUsage } from '@mcp-trace/trace-core'
import { cleanContext, endContext, getContext, startContext } from '@mcp-trace/trace-web'
@ -16,7 +17,6 @@ import { Model, Topic } from '@renderer/types'
import type { Message } from '@renderer/types/newMessage'
import { MessageBlockType } from '@renderer/types/newMessage'
import { SdkRawChunk } from '@renderer/types/sdk'
import { Stream } from 'openai/streaming'
const logger = loggerService.withContext('SpanManagerService')

View File

@ -6,6 +6,8 @@ import {
WebSearchResultBlock,
WebSearchToolResultError
} from '@anthropic-ai/sdk/resources/messages'
import OpenAI from '@cherrystudio/openai'
import { ChatCompletionChunk } from '@cherrystudio/openai/resources'
import { FinishReason, MediaModality } from '@google/genai'
import { FunctionCall } from '@google/genai'
import AiProvider from '@renderer/aiCore'
@ -38,8 +40,6 @@ import {
import { mcpToolCallResponseToGeminiMessage } from '@renderer/utils/mcp-tools'
import * as McpToolsModule from '@renderer/utils/mcp-tools'
import { cloneDeep } from 'lodash'
import OpenAI from 'openai'
import { ChatCompletionChunk } from 'openai/resources'
import { beforeEach, describe, expect, it, vi } from 'vitest'
// Mock the ApiClientFactory
vi.mock('@renderer/aiCore/legacy/clients/ApiClientFactory', () => ({

View File

@ -1,5 +1,5 @@
import { ChatCompletionMessageParam } from '@cherrystudio/openai/resources'
import type { Model } from '@renderer/types'
import { ChatCompletionMessageParam } from 'openai/resources'
import { describe, expect, it } from 'vitest'
import { processReqMessages } from '../ModelMessageService'

View File

@ -1,10 +1,10 @@
import { WebSearchResultBlock } from '@anthropic-ai/sdk/resources'
import type OpenAI from '@cherrystudio/openai'
import type { GroundingMetadata } from '@google/genai'
import { createEntityAdapter, createSelector, createSlice, type PayloadAction } from '@reduxjs/toolkit'
import { AISDKWebSearchResult, Citation, WebSearchProviderResponse, WebSearchSource } from '@renderer/types'
import type { CitationMessageBlock, MessageBlock } from '@renderer/types/newMessage'
import { MessageBlockType } from '@renderer/types/newMessage'
import type OpenAI from 'openai'
import type { RootState } from './index' // 确认 RootState 从 store/index.ts 导出

View File

@ -1,8 +1,8 @@
import { OpenAI } from '@cherrystudio/openai'
import { Stream } from '@cherrystudio/openai/streaming'
import { TokenUsage } from '@mcp-trace/trace-core'
import { Span } from '@opentelemetry/api'
import { endSpan } from '@renderer/services/SpanManagerService'
import { OpenAI } from 'openai'
import { Stream } from 'openai/streaming'
export class StreamHandler {
private topicId: string

View File

@ -1,6 +1,6 @@
import type OpenAI from '@cherrystudio/openai'
import type { File } from '@google/genai'
import type { FileSchema } from '@mistralai/mistralai/models/components'
import type OpenAI from 'openai'
export type RemoteFile =
| {

View File

@ -1,7 +1,7 @@
import type { LanguageModelV2Source } from '@ai-sdk/provider'
import type { WebSearchResultBlock } from '@anthropic-ai/sdk/resources'
import type OpenAI from '@cherrystudio/openai'
import type { GenerateImagesConfig, GroundingMetadata, PersonGeneration } from '@google/genai'
import type OpenAI from 'openai'
import type { CSSProperties } from 'react'
export * from './file'

View File

@ -1,5 +1,5 @@
import type { CompletionUsage } from '@cherrystudio/openai/resources'
import type { ProviderMetadata } from 'ai'
import type { CompletionUsage } from 'openai/resources'
import type {
Assistant,

View File

@ -11,6 +11,9 @@ import { MessageStream } from '@anthropic-ai/sdk/resources/messages/messages'
import AnthropicVertex from '@anthropic-ai/vertex-sdk'
import type { BedrockClient } from '@aws-sdk/client-bedrock'
import type { BedrockRuntimeClient } from '@aws-sdk/client-bedrock-runtime'
import OpenAI, { AzureOpenAI } from '@cherrystudio/openai'
import { ChatCompletionContentPartImage } from '@cherrystudio/openai/resources'
import { Stream } from '@cherrystudio/openai/streaming'
import {
Content,
CreateChatParameters,
@ -21,9 +24,6 @@ import {
SendMessageParameters,
Tool
} from '@google/genai'
import OpenAI, { AzureOpenAI } from 'openai'
import { ChatCompletionContentPartImage } from 'openai/resources'
import { Stream } from 'openai/streaming'
import { EndpointType } from './index'

View File

@ -1,4 +1,11 @@
import { ContentBlockParam, MessageParam, ToolUnion, ToolUseBlock } from '@anthropic-ai/sdk/resources'
import OpenAI from '@cherrystudio/openai'
import {
ChatCompletionContentPart,
ChatCompletionMessageParam,
ChatCompletionMessageToolCall,
ChatCompletionTool
} from '@cherrystudio/openai/resources'
import { Content, FunctionCall, Part, Tool, Type as GeminiSchemaType } from '@google/genai'
import { loggerService } from '@logger'
import { isFunctionCallingModel, isVisionModel } from '@renderer/config/models'
@ -21,13 +28,6 @@ import { ChunkType } from '@renderer/types/chunk'
import { AwsBedrockSdkMessageParam, AwsBedrockSdkTool, AwsBedrockSdkToolCall } from '@renderer/types/sdk'
import { t } from 'i18next'
import { nanoid } from 'nanoid'
import OpenAI from 'openai'
import {
ChatCompletionContentPart,
ChatCompletionMessageParam,
ChatCompletionMessageToolCall,
ChatCompletionTool
} from 'openai/resources'
import { isToolUseModeFunction } from './assistant'
import { convertBase64ImageToAwsBedrockFormat } from './aws-bedrock-utils'

View File

@ -2639,6 +2639,23 @@ __metadata:
languageName: unknown
linkType: soft
"@cherrystudio/openai@npm:6.3.0-fork.1":
version: 6.3.0-fork.1
resolution: "@cherrystudio/openai@npm:6.3.0-fork.1"
peerDependencies:
ws: ^8.18.0
zod: ^3.25 || ^4.0
peerDependenciesMeta:
ws:
optional: true
zod:
optional: true
bin:
openai: bin/cli
checksum: 10c0/dc8c5555aa6d12cd47586efc70175ec1bf7112c1f737b28d86d26e9666535d9e87d1c4811a069d11c324bab56f4dae242d7266efa88359d0926c7059240d24cc
languageName: node
linkType: hard
"@chevrotain/cst-dts-gen@npm:11.0.3":
version: 11.0.3
resolution: "@chevrotain/cst-dts-gen@npm:11.0.3"
@ -14253,6 +14270,7 @@ __metadata:
"@cherrystudio/embedjs-ollama": "npm:^0.1.31"
"@cherrystudio/embedjs-openai": "npm:^0.1.31"
"@cherrystudio/extension-table-plus": "workspace:^"
"@cherrystudio/openai": "npm:6.3.0-fork.1"
"@dnd-kit/core": "npm:^6.3.1"
"@dnd-kit/modifiers": "npm:^9.0.0"
"@dnd-kit/sortable": "npm:^10.0.0"
@ -14432,7 +14450,6 @@ __metadata:
notion-helper: "npm:^1.3.22"
npx-scope-finder: "npm:^1.2.0"
officeparser: "npm:^4.2.0"
openai: "patch:openai@npm%3A5.12.2#~/.yarn/patches/openai-npm-5.12.2-30b075401c.patch"
os-proxy-config: "npm:^1.1.2"
oxlint: "npm:^1.15.0"
oxlint-tsgolint: "npm:^0.2.0"