From ee7761ea356341e4af70c45b8c7f9b2901f92c29 Mon Sep 17 00:00:00 2001 From: zerob13 Date: Mon, 13 Oct 2025 20:44:54 +0800 Subject: [PATCH 1/5] feat: add cherryin provider --- .../presenter/configPresenter/providers.ts | 15 +++ .../presenter/llmProviderPresenter/index.ts | 5 + .../providers/cherryInProvider.ts | 89 ++++++++++++++++++ .../src/assets/llm-icons/cherryin-color.png | Bin 0 -> 11327 bytes .../src/components/icons/ModelIcon.vue | 2 + 5 files changed, 111 insertions(+) create mode 100644 src/main/presenter/llmProviderPresenter/providers/cherryInProvider.ts create mode 100644 src/renderer/src/assets/llm-icons/cherryin-color.png diff --git a/src/main/presenter/configPresenter/providers.ts b/src/main/presenter/configPresenter/providers.ts index 73cecbbba..0def82092 100644 --- a/src/main/presenter/configPresenter/providers.ts +++ b/src/main/presenter/configPresenter/providers.ts @@ -124,6 +124,21 @@ export const DEFAULT_PROVIDERS: LLM_PROVIDER_BASE[] = [ defaultBaseUrl: 'https://api.openai.com/v1' } }, + { + id: 'cherryInProvider', + name: 'CherryIn', + apiType: 'cherryin-responses', + apiKey: '', + baseUrl: 'https://open.cherryin.ai/v1', + enable: false, + websites: { + official: 'https://open.cherryin.ai/console', + apiKey: 'https://open.cherryin.ai/console', + docs: 'https://docs.newapi.pro/api/openai-responses/', + models: 'https://docs.newapi.pro/api/openai-responses/', + defaultBaseUrl: 'https://open.cherryin.ai/v1' + } + }, { id: 'openai', name: 'OpenAI', diff --git a/src/main/presenter/llmProviderPresenter/index.ts b/src/main/presenter/llmProviderPresenter/index.ts index 96d82a76d..23fadbc87 100644 --- a/src/main/presenter/llmProviderPresenter/index.ts +++ b/src/main/presenter/llmProviderPresenter/index.ts @@ -40,6 +40,7 @@ import { presenter } from '@/presenter' import { ZhipuProvider } from './providers/zhipuProvider' import { LMStudioProvider } from './providers/lmstudioProvider' import { OpenAIResponsesProvider } from './providers/openAIResponsesProvider' +import { CherryInProvider } from './providers/cherryInProvider' import { OpenRouterProvider } from './providers/openRouterProvider' import { MinimaxProvider } from './providers/minimaxProvider' import { AihubmixProvider } from './providers/aihubmixProvider' @@ -201,6 +202,8 @@ export class LLMProviderPresenter implements ILlmProviderPresenter { return new OpenAIProvider(provider, this.configPresenter) case 'openai-responses': return new OpenAIResponsesProvider(provider, this.configPresenter) + case 'cherryInProvider': + return new CherryInProvider(provider, this.configPresenter) case 'lmstudio': return new LMStudioProvider(provider, this.configPresenter) case 'together': @@ -251,6 +254,8 @@ export class LLMProviderPresenter implements ILlmProviderPresenter { return new OpenAICompatibleProvider(provider, this.configPresenter) case 'openai-responses': return new OpenAIResponsesProvider(provider, this.configPresenter) + case 'cherryin-responses': + return new CherryInProvider(provider, this.configPresenter) case 'lmstudio': return new LMStudioProvider(provider, this.configPresenter) case 'together': diff --git a/src/main/presenter/llmProviderPresenter/providers/cherryInProvider.ts b/src/main/presenter/llmProviderPresenter/providers/cherryInProvider.ts new file mode 100644 index 000000000..47613e6c1 --- /dev/null +++ b/src/main/presenter/llmProviderPresenter/providers/cherryInProvider.ts @@ -0,0 +1,89 @@ +import { LLM_PROVIDER, MODEL_META, IConfigPresenter } from '@shared/presenter' +import { OpenAICompatibleProvider } from './openAICompatibleProvider' + +const CHERRYIN_FALLBACK_MODELS: Omit[] = [ + { + id: 'gpt-4.1', + name: 'GPT-4.1', + group: 'cherryin', + isCustom: false, + vision: true, + functionCall: true, + reasoning: true, + contextLength: 128000, + maxTokens: 4096 + }, + { + id: 'gpt-4.1-mini', + name: 'GPT-4.1 Mini', + group: 'cherryin', + isCustom: false, + vision: true, + functionCall: true, + reasoning: false, + contextLength: 128000, + maxTokens: 8192 + }, + { + id: 'gpt-4o', + name: 'GPT-4o', + group: 'cherryin', + isCustom: false, + vision: true, + functionCall: true, + reasoning: true, + contextLength: 128000, + maxTokens: 16384 + }, + { + id: 'gpt-4o-mini', + name: 'GPT-4o Mini', + group: 'cherryin', + isCustom: false, + vision: true, + functionCall: true, + reasoning: false, + contextLength: 128000, + maxTokens: 16384 + }, + { + id: 'o3-mini', + name: 'O3 Mini', + group: 'cherryin', + isCustom: false, + vision: false, + functionCall: true, + reasoning: true, + contextLength: 200000, + maxTokens: 64000 + } +] + +export class CherryInProvider extends OpenAICompatibleProvider { + constructor(provider: LLM_PROVIDER, configPresenter: IConfigPresenter) { + super(provider, configPresenter) + } + + protected async fetchOpenAIModels(options?: { timeout: number }): Promise { + try { + const models = await super.fetchOpenAIModels(options) + if (models.length > 0) { + return models.map((model) => ({ + ...model, + group: model.group === 'default' ? 'cherryin' : model.group, + providerId: this.provider.id + })) + } + } catch (error) { + console.warn( + '[CherryInProvider] Failed to fetch models via API, falling back to defaults', + error + ) + } + + return CHERRYIN_FALLBACK_MODELS.map((model) => ({ + ...model, + providerId: this.provider.id + })) + } +} diff --git a/src/renderer/src/assets/llm-icons/cherryin-color.png b/src/renderer/src/assets/llm-icons/cherryin-color.png new file mode 100644 index 0000000000000000000000000000000000000000..ff4a6c079996f8f722a0485ace5a2b2e8ea1ba2e GIT binary patch literal 11327 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 literal 0 HcmV?d00001 diff --git a/src/renderer/src/components/icons/ModelIcon.vue b/src/renderer/src/components/icons/ModelIcon.vue index 782b78f52..b1464e1c9 100644 --- a/src/renderer/src/components/icons/ModelIcon.vue +++ b/src/renderer/src/components/icons/ModelIcon.vue @@ -1,5 +1,6 @@