diff --git a/Dockerfile b/Dockerfile index 272d53d49a86d..a04fe07ef5193 100644 --- a/Dockerfile +++ b/Dockerfile @@ -157,6 +157,8 @@ ENV \ BAICHUAN_API_KEY="" BAICHUAN_MODEL_LIST="" \ # Cloudflare CLOUDFLARE_API_KEY="" CLOUDFLARE_BASE_URL_OR_ACCOUNT_ID="" CLOUDFLARE_MODEL_LIST="" \ + # Cohere + COHERE_API_KEY="" COHERE_MODEL_LIST="" COHERE_PROXY_URL="" \ # DeepSeek DEEPSEEK_API_KEY="" DEEPSEEK_MODEL_LIST="" \ # Fireworks AI diff --git a/Dockerfile.database b/Dockerfile.database index abd9108d4462f..1df8987b5fa18 100644 --- a/Dockerfile.database +++ b/Dockerfile.database @@ -200,6 +200,8 @@ ENV \ BAICHUAN_API_KEY="" BAICHUAN_MODEL_LIST="" \ # Cloudflare CLOUDFLARE_API_KEY="" CLOUDFLARE_BASE_URL_OR_ACCOUNT_ID="" CLOUDFLARE_MODEL_LIST="" \ + # Cohere + COHERE_API_KEY="" COHERE_MODEL_LIST="" COHERE_PROXY_URL="" \ # DeepSeek DEEPSEEK_API_KEY="" DEEPSEEK_MODEL_LIST="" \ # Fireworks AI diff --git a/Dockerfile.pglite b/Dockerfile.pglite index d694cea6eaac7..c0309ca8947d1 100644 --- a/Dockerfile.pglite +++ b/Dockerfile.pglite @@ -158,6 +158,8 @@ ENV \ BAICHUAN_API_KEY="" BAICHUAN_MODEL_LIST="" \ # Cloudflare CLOUDFLARE_API_KEY="" CLOUDFLARE_BASE_URL_OR_ACCOUNT_ID="" CLOUDFLARE_MODEL_LIST="" \ + # Cohere + COHERE_API_KEY="" COHERE_MODEL_LIST="" COHERE_PROXY_URL="" \ # DeepSeek DEEPSEEK_API_KEY="" DEEPSEEK_MODEL_LIST="" \ # Fireworks AI diff --git a/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx b/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx index 6d503a1aae6d6..05176e79fcddc 100644 --- a/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx +++ b/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx @@ -5,6 +5,7 @@ import { Ai360ProviderCard, AnthropicProviderCard, BaichuanProviderCard, + CohereProviderCard, DeepSeekProviderCard, FireworksAIProviderCard, GiteeAIProviderCard, @@ -82,6 +83,7 @@ export const useProviderList = (): ProviderItem[] => { XAIProviderCard, JinaProviderCard, SambaNovaProviderCard, + CohereProviderCard, QwenProviderCard, WenxinProviderCard, HunyuanProviderCard, diff --git a/src/config/aiModels/cohere.ts b/src/config/aiModels/cohere.ts new file mode 100644 index 0000000000000..05d8082573c58 --- /dev/null +++ b/src/config/aiModels/cohere.ts @@ -0,0 +1,243 @@ +import { AIChatModelCard } from '@/types/aiModel'; + +const cohereChatModels: AIChatModelCard[] = [ + { + abilities: { + functionCall: true, + }, + contextWindowTokens: 256_000, + description: + 'Command A 是我们迄今为止性能最强的模型,在工具使用、代理、检索增强生成(RAG)和多语言应用场景方面表现出色。Command A 具有 256K 的上下文长度,仅需两块 GPU 即可运行,并且相比于 Command R+ 08-2024,吞吐量提高了 150%。', + displayName: 'Command A 03-2025', + enabled: true, + id: 'command-a-03-2025', + maxOutput: 8000, + pricing: { + input: 2.5, + output: 10 + }, + type: 'chat' + }, + { + abilities: { + functionCall: true, + }, + contextWindowTokens: 128_000, + description: + 'command-r-plus 是 command-r-plus-04-2024 的别名,因此如果您在 API 中使用 command-r-plus,实际上指向的就是该模型。', + displayName: 'Command R+', + enabled: true, + id: 'command-r-plus', + maxOutput: 4000, + pricing: { + input: 2.5, + output: 10 + }, + type: 'chat' + }, + { + abilities: { + functionCall: true, + }, + contextWindowTokens: 128_000, + description: + 'Command R+ 是一个遵循指令的对话模型,在语言任务方面表现出更高的质量、更可靠,并且相比以往模型具有更长的上下文长度。它最适用于复杂的 RAG 工作流和多步工具使用。', + displayName: 'Command R+ 04-2024', + id: 'command-r-plus-04-2024', + maxOutput: 4000, + pricing: { + input: 3, + output: 15 + }, + type: 'chat' + }, + { + abilities: { + functionCall: true, + }, + contextWindowTokens: 128_000, + description: + 'command-r 是 command-c-03-2024 的别名,因此如果您在 API 中使用 command-r,实际上指向的就是该模型。', + displayName: 'Command R', + enabled: true, + id: 'command-r', + maxOutput: 4000, + pricing: { + input: 0.15, + output: 0.6 + }, + type: 'chat' + }, + { + abilities: { + functionCall: true, + }, + contextWindowTokens: 128_000, + description: + 'command-r-08-2024 是 Command R 模型的更新版本,于 2024 年 8 月发布。', + displayName: 'Command R 08-2024', + id: 'command-r-08-2024', + maxOutput: 4000, + pricing: { + input: 0.15, + output: 0.6 + }, + type: 'chat' + }, + { + abilities: { + functionCall: true, + }, + contextWindowTokens: 128_000, + description: + 'Command R 是一个遵循指令的对话模型,在语言任务方面表现出更高的质量、更可靠,并且相比以往模型具有更长的上下文长度。它可用于复杂的工作流程,如代码生成、检索增强生成(RAG)、工具使用和代理。', + displayName: 'Command R 03-2024', + id: 'command-r-03-2024', + maxOutput: 4000, + pricing: { + input: 0.5, + output: 1.5 + }, + type: 'chat' + }, + { + abilities: { + functionCall: true, + }, + contextWindowTokens: 128_000, + description: + 'command-r7b-12-2024 是一个小型且高效的更新版本,于 2024 年 12 月发布。它在 RAG、工具使用、代理等需要复杂推理和多步处理的任务中表现出色。', + displayName: 'Command R7B 12-2024', + enabled: true, + id: 'command-r7b-12-2024', + maxOutput: 4000, + pricing: { + input: 0.0375, + output: 0.15 + }, + type: 'chat' + }, + { + contextWindowTokens: 4000, + description: + '一个遵循指令的对话模型,在语言任务中表现出高质量、更可靠,并且相比我们的基础生成模型具有更长的上下文长度。', + displayName: 'Command', + enabled: true, + id: 'command', + maxOutput: 4000, + pricing: { + input: 1, + output: 2 + }, + type: 'chat' + }, + { + abilities: { + functionCall: true, + }, + contextWindowTokens: 128_000, + description: + '为了缩短主要版本发布之间的时间间隔,我们推出了 Command 模型的每夜版本。对于 Command 系列,这一版本称为 command-cightly。请注意,command-nightly 是最新、最具实验性且(可能)不稳定的版本。每夜版本会定期更新,且不会提前通知,因此不建议在生产环境中使用。', + displayName: 'Command Nightly', + id: 'command-nightly', + maxOutput: 4000, + pricing: { + input: 1, + output: 2 + }, + type: 'chat' + }, + { + contextWindowTokens: 4000, + description: + '一个更小、更快的 Command 版本,几乎同样强大,但速度更快。', + displayName: 'Command Light', + enabled: true, + id: 'command-light', + maxOutput: 4000, + pricing: { + input: 0.3, + output: 0.6 + }, + type: 'chat' + }, + { + contextWindowTokens: 4000, + description: + '为了缩短主要版本发布之间的时间间隔,我们推出了 Command 模型的每夜版本。对于 command-light 系列,这一版本称为 command-light-nightly。请注意,command-light-nightly 是最新、最具实验性且(可能)不稳定的版本。每夜版本会定期更新,且不会提前通知,因此不建议在生产环境中使用。', + displayName: 'Command Light Nightly', + id: 'command-light-nightly', + maxOutput: 4000, + pricing: { + input: 0.3, + output: 0.6 + }, + type: 'chat' + }, + { + contextWindowTokens: 128_000, + description: + 'Aya Expanse 是一款高性能的 32B 多语言模型,旨在通过指令调优、数据套利、偏好训练和模型合并的创新,挑战单语言模型的表现。它支持 23 种语言。', + displayName: 'Aya Expanse 32B', + enabled: true, + id: 'c4ai-aya-expanse-32b', + maxOutput: 4000, + pricing: { + input: 0.5, + output: 1.5 + }, + type: 'chat' + }, + { + contextWindowTokens: 8000, + description: + 'Aya Expanse 是一款高性能的 8B 多语言模型,旨在通过指令调优、数据套利、偏好训练和模型合并的创新,挑战单语言模型的表现。它支持 23 种语言。', + displayName: 'Aya Expanse 8B', + enabled: true, + id: 'c4ai-aya-expanse-8b', + maxOutput: 4000, + pricing: { + input: 0.5, + output: 1.5 + }, + type: 'chat' + }, + { + abilities: { + vision: true, + }, + contextWindowTokens: 16_000, + description: + 'Aya Vision 是一款最先进的多模态模型,在语言、文本和图像能力的多个关键基准上表现出色。它支持 23 种语言。这个 320 亿参数的版本专注于最先进的多语言表现。', + displayName: 'Aya Vision 32B', + enabled: true, + id: 'c4ai-aya-vision-32b', + maxOutput: 4000, + pricing: { + input: 0.5, + output: 1.5 + }, + type: 'chat' + }, + { + abilities: { + vision: true, + }, + contextWindowTokens: 16_000, + description: + 'Aya Vision 是一款最先进的多模态模型,在语言、文本和图像能力的多个关键基准上表现出色。这个 80 亿参数的版本专注于低延迟和最佳性能。', + displayName: 'Aya Vision 8B', + enabled: true, + id: 'c4ai-aya-vision-8b', + maxOutput: 4000, + pricing: { + input: 0.5, + output: 1.5 + }, + type: 'chat' + }, +] + +export const allModels = [...cohereChatModels]; + +export default allModels; diff --git a/src/config/aiModels/index.ts b/src/config/aiModels/index.ts index 7cd0ed49c669d..da4936415d762 100644 --- a/src/config/aiModels/index.ts +++ b/src/config/aiModels/index.ts @@ -8,6 +8,7 @@ import { default as azureai } from './azureai'; import { default as baichuan } from './baichuan'; import { default as bedrock } from './bedrock'; import { default as cloudflare } from './cloudflare'; +import { default as cohere } from './cohere'; import { default as deepseek } from './deepseek'; import { default as doubao } from './doubao'; import { default as fireworksai } from './fireworksai'; @@ -77,6 +78,7 @@ export const LOBE_DEFAULT_MODEL_LIST = buildDefaultModelList({ baichuan, bedrock, cloudflare, + cohere, deepseek, doubao, fireworksai, @@ -127,6 +129,7 @@ export { default as azureai } from './azureai'; export { default as baichuan } from './baichuan'; export { default as bedrock } from './bedrock'; export { default as cloudflare } from './cloudflare'; +export { default as cohere } from './cohere'; export { default as deepseek } from './deepseek'; export { default as doubao } from './doubao'; export { default as fireworksai } from './fireworksai'; diff --git a/src/config/llm.ts b/src/config/llm.ts index c4e1411c454a5..f0637da3d8ba9 100644 --- a/src/config/llm.ts +++ b/src/config/llm.ts @@ -150,6 +150,9 @@ export const getLLMConfig = () => { ENABLED_PPIO: z.boolean(), PPIO_API_KEY: z.string().optional(), + + ENABLED_COHERE: z.boolean(), + COHERE_API_KEY: z.string().optional(), }, runtimeEnv: { API_KEY_SELECT_MODE: process.env.API_KEY_SELECT_MODE, @@ -298,6 +301,9 @@ export const getLLMConfig = () => { ENABLED_PPIO: !!process.env.PPIO_API_KEY, PPIO_API_KEY: process.env.PPIO_API_KEY, + + ENABLED_COHERE: !!process.env.COHERE_API_KEY, + COHERE_API_KEY: process.env.COHERE_API_KEY, }, }); }; diff --git a/src/config/modelProviders/cohere.ts b/src/config/modelProviders/cohere.ts new file mode 100644 index 0000000000000..8380cd33399b3 --- /dev/null +++ b/src/config/modelProviders/cohere.ts @@ -0,0 +1,19 @@ +import { ModelProviderCard } from '@/types/llm'; + +const Cohere: ModelProviderCard = { + chatModels: [], + checkModel: 'command-r7b-12-2024', + description: 'Cohere 为您带来最前沿的多语言模型、先进的检索功能以及为现代企业量身定制的 AI 工作空间 — 一切都集成在一个安全的平台中。', + id: 'cohere', + modelsUrl: 'https://docs.cohere.com/v2/docs/models', + name: 'Cohere', + settings: { + proxyUrl: { + placeholder: 'https://api.cohere.ai/compatibility/v1', + }, + sdkType: 'openai', + }, + url: 'https://cohere.com', +}; + +export default Cohere; diff --git a/src/config/modelProviders/index.ts b/src/config/modelProviders/index.ts index 84b8d701264e2..f8271ecb7a21d 100644 --- a/src/config/modelProviders/index.ts +++ b/src/config/modelProviders/index.ts @@ -8,6 +8,7 @@ import AzureAIProvider from './azureai'; import BaichuanProvider from './baichuan'; import BedrockProvider from './bedrock'; import CloudflareProvider from './cloudflare'; +import CohereProvider from './cohere'; import DeepSeekProvider from './deepseek'; import DoubaoProvider from './doubao'; import FireworksAIProvider from './fireworksai'; @@ -75,6 +76,7 @@ export const LOBE_DEFAULT_MODEL_LIST: ChatModelCard[] = [ XAIProvider.chatModels, JinaProvider.chatModels, SambaNovaProvider.chatModels, + CohereProvider.chatModels, ZeroOneProvider.chatModels, StepfunProvider.chatModels, NovitaProvider.chatModels, @@ -124,6 +126,7 @@ export const DEFAULT_MODEL_PROVIDER_LIST = [ XAIProvider, JinaProvider, SambaNovaProvider, + CohereProvider, QwenProvider, WenxinProvider, TencentcloudProvider, @@ -164,6 +167,7 @@ export { default as AzureAIProviderCard } from './azureai'; export { default as BaichuanProviderCard } from './baichuan'; export { default as BedrockProviderCard } from './bedrock'; export { default as CloudflareProviderCard } from './cloudflare'; +export { default as CohereProviderCard } from './cohere'; export { default as DeepSeekProviderCard } from './deepseek'; export { default as DoubaoProviderCard } from './doubao'; export { default as FireworksAIProviderCard } from './fireworksai'; diff --git a/src/libs/agent-runtime/cohere/index.ts b/src/libs/agent-runtime/cohere/index.ts new file mode 100644 index 0000000000000..89bf9303a20d6 --- /dev/null +++ b/src/libs/agent-runtime/cohere/index.ts @@ -0,0 +1,69 @@ +import { ModelProvider } from '../types'; +import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; + +import type { ChatModelCard } from '@/types/llm'; + +export interface CohereModelCard { + context_length: number; + features: string[] | null; + name: string; + supports_vision: boolean; +} + +export const LobeCohereAI = LobeOpenAICompatibleFactory({ + baseURL: 'https://api.cohere.ai/compatibility/v1', + chatCompletion: { + // https://docs.cohere.com/v2/docs/compatibility-api#unsupported-parameters + excludeUsage: true, + handlePayload: (payload) => { + const { frequency_penalty, presence_penalty, top_p, ...rest } = payload; + + return { + ...rest, + frequency_penalty: + frequency_penalty !== undefined && frequency_penalty > 0 && frequency_penalty <= 1 + ? frequency_penalty + : undefined, + presence_penalty: + presence_penalty !== undefined && presence_penalty > 0 && presence_penalty <= 1 + ? presence_penalty + : undefined, + top_p: top_p !== undefined && top_p > 0 && top_p < 1 ? top_p : undefined, + } as any; + }, + noUserId: true, + }, + debug: { + chatCompletion: () => process.env.DEBUG_COHERE_CHAT_COMPLETION === '1', + }, + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); + + client.baseURL = 'https://api.cohere.com/v1'; + + const modelsPage = await client.models.list() as any; + const modelList: CohereModelCard[] = modelsPage.body.models; + + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.name.toLowerCase() === m.id.toLowerCase()); + + return { + contextWindowTokens: model.context_length, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + (model.features && model.features.includes("tools")) + || knownModel?.abilities?.functionCall + || false, + id: model.name, + vision: + model.supports_vision + || knownModel?.abilities?.vision + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; + }, + provider: ModelProvider.Cohere, +}); diff --git a/src/libs/agent-runtime/runtimeMap.ts b/src/libs/agent-runtime/runtimeMap.ts index fbe1d080070cb..e5d2b55192bbd 100644 --- a/src/libs/agent-runtime/runtimeMap.ts +++ b/src/libs/agent-runtime/runtimeMap.ts @@ -6,6 +6,7 @@ import { LobeAzureAI } from './azureai'; import { LobeBaichuanAI } from './baichuan'; import LobeBedrockAI from './bedrock'; import { LobeCloudflareAI } from './cloudflare'; +import { LobeCohereAI } from './cohere'; import { LobeDeepSeekAI } from './deepseek'; import { LobeFireworksAI } from './fireworksai'; import { LobeGiteeAI } from './giteeai'; @@ -54,6 +55,7 @@ export const providerRuntimeMap = { baichuan: LobeBaichuanAI, bedrock: LobeBedrockAI, cloudflare: LobeCloudflareAI, + cohere: LobeCohereAI, deepseek: LobeDeepSeekAI, doubao: LobeVolcengineAI, fireworksai: LobeFireworksAI, diff --git a/src/libs/agent-runtime/types/type.ts b/src/libs/agent-runtime/types/type.ts index 80ca857f49f29..c64a002e1677f 100644 --- a/src/libs/agent-runtime/types/type.ts +++ b/src/libs/agent-runtime/types/type.ts @@ -30,6 +30,7 @@ export enum ModelProvider { Baichuan = 'baichuan', Bedrock = 'bedrock', Cloudflare = 'cloudflare', + Cohere = 'cohere', DeepSeek = 'deepseek', /** * @deprecated diff --git a/src/types/user/settings/keyVaults.ts b/src/types/user/settings/keyVaults.ts index bf0abcb21fe7f..2bac7c43c5130 100644 --- a/src/types/user/settings/keyVaults.ts +++ b/src/types/user/settings/keyVaults.ts @@ -41,6 +41,7 @@ export interface UserKeyVaults extends SearchEngineKeyVaults { baichuan?: OpenAICompatibleKeyVault; bedrock?: AWSBedrockKeyVault; cloudflare?: CloudflareKeyVault; + cohere?: OpenAICompatibleKeyVault; deepseek?: OpenAICompatibleKeyVault; doubao?: OpenAICompatibleKeyVault; fireworksai?: OpenAICompatibleKeyVault;