From f2996ebb1885c4131dbb795604415e6ee2b298f2 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 31 May 2024 22:37:48 +0800 Subject: [PATCH 01/38] Delete .nvmrc --- .nvmrc | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .nvmrc diff --git a/.nvmrc b/.nvmrc deleted file mode 100644 index a77793ecc520..000000000000 --- a/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -lts/hydrogen From 4b1d4c62738b2748788e20e89e2a8f9b34b19af4 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 15:13:36 +0800 Subject: [PATCH 02/38] feat: Add Cloudflare as a model provider This commit adds support for Cloudflare as a model provider. It includes changes to the `ModelProvider` enum, the `UserKeyVaults` interface, the `getServerGlobalConfig` function, the `DEFAULT_LLM_CONFIG` constant, the `getLLMConfig` function, the `AgentRuntime` class, and the `DEFAULT_MODEL_PROVIDER_LIST` constant. --- .../settings/llm/ProviderList/providers.tsx | 54 ++++++------------- src/app/api/chat/agentRuntime.ts | 9 ++-- src/config/llm.ts | 7 +++ src/config/modelProviders/cloudflare.ts | 20 +++++++ src/config/modelProviders/index.ts | 4 ++ src/const/settings/llm.ts | 5 ++ src/libs/agent-runtime/AgentRuntime.ts | 6 +++ src/libs/agent-runtime/cloudflare/index.ts | 21 ++++++++ src/libs/agent-runtime/types/type.ts | 1 + src/server/globalConfig/index.ts | 2 + src/types/user/settings/keyVaults.ts | 6 +++ 11 files changed, 94 insertions(+), 41 deletions(-) create mode 100644 src/config/modelProviders/cloudflare.ts create mode 100644 src/libs/agent-runtime/cloudflare/index.ts diff --git a/src/app/(main)/settings/llm/ProviderList/providers.tsx b/src/app/(main)/settings/llm/ProviderList/providers.tsx index 39258bb13964..fbec7d42ed84 100644 --- a/src/app/(main)/settings/llm/ProviderList/providers.tsx +++ b/src/app/(main)/settings/llm/ProviderList/providers.tsx @@ -1,6 +1,7 @@ import { Anthropic, Claude, + Cloudflare, DeepSeek, Gemini, Google, @@ -10,9 +11,9 @@ import { Moonshot, OpenRouter, Perplexity, - Stepfun, Together, Tongyi, + WorkersAI, ZeroOne, Zhipu, } from '@lobehub/icons'; @@ -20,10 +21,10 @@ import { Divider } from 'antd'; import { useTheme } from 'antd-style'; import { useMemo } from 'react'; import { Flexbox } from 'react-layout-kit'; -import urlJoin from 'url-join'; import { AnthropicProviderCard, + CloudflareProviderCard, DeepSeekProviderCard, GoogleProviderCard, GroqProviderCard, @@ -33,7 +34,6 @@ import { OpenRouterProviderCard, PerplexityProviderCard, QwenProviderCard, - StepfunProviderCard, TogetherAIProviderCard, ZeroOneProviderCard, ZhiPuProviderCard, @@ -45,8 +45,6 @@ import { useBedrockProvider } from './Bedrock'; import { useOllamaProvider } from './Ollama'; import { useOpenAIProvider } from './OpenAI'; -const BASE_DOC_URL = 'https://lobehub.com/docs/usage/providers'; - const AnthropicBrand = () => { const { isDarkMode } = useTheme(); return ; @@ -76,6 +74,14 @@ const GoogleBrand = () => ( ); +const CloudflareBrand = () => ( + + + + + +); + export const useProviderList = (): ProviderItem[] => { const azureProvider = useAzureProvider(); const ollamaProvider = useOllamaProvider(); @@ -84,91 +90,65 @@ export const useProviderList = (): ProviderItem[] => { return useMemo( () => [ - { - ...openAIProvider, - docUrl: urlJoin(BASE_DOC_URL, 'openai'), - }, - { - ...ollamaProvider, - docUrl: urlJoin(BASE_DOC_URL, 'ollama'), - }, - { - ...azureProvider, - docUrl: urlJoin(BASE_DOC_URL, 'azure'), - }, + openAIProvider, + ollamaProvider, + azureProvider, { ...GoogleProviderCard, - docUrl: urlJoin(BASE_DOC_URL, 'gemini'), title: , }, { ...AnthropicProviderCard, - docUrl: urlJoin(BASE_DOC_URL, 'anthropic'), title: , }, - { - ...bedrockProvider, - docUrl: urlJoin(BASE_DOC_URL, 'bedrock'), - }, + bedrockProvider, { ...GroqProviderCard, - docUrl: urlJoin(BASE_DOC_URL, 'groq'), title: , }, { ...OpenRouterProviderCard, - docUrl: urlJoin(BASE_DOC_URL, 'openrouter'), title: , }, { ...TogetherAIProviderCard, - docUrl: urlJoin(BASE_DOC_URL, 'togetherai'), title: , }, { ...QwenProviderCard, - docUrl: urlJoin(BASE_DOC_URL, 'qwen'), title: , }, { ...DeepSeekProviderCard, - docUrl: urlJoin(BASE_DOC_URL, 'deepseek'), title: , }, { ...MinimaxProviderCard, - docUrl: urlJoin(BASE_DOC_URL, 'minimax'), title: , }, { ...MistralProviderCard, - docUrl: urlJoin(BASE_DOC_URL, 'mistral'), title: , }, { ...MoonshotProviderCard, - docUrl: urlJoin(BASE_DOC_URL, 'moonshot'), title: , }, { ...PerplexityProviderCard, - docUrl: urlJoin(BASE_DOC_URL, 'perplexity'), title: , }, { ...ZhiPuProviderCard, - docUrl: urlJoin(BASE_DOC_URL, 'zhipu'), title: , }, { ...ZeroOneProviderCard, - docUrl: urlJoin(BASE_DOC_URL, '01ai'), title: , }, { - ...StepfunProviderCard, - docUrl: urlJoin(BASE_DOC_URL, 'stepfun'), - title: , + ...CloudflareProviderCard, + title: , }, ], [azureProvider, ollamaProvider, ollamaProvider, bedrockProvider], diff --git a/src/app/api/chat/agentRuntime.ts b/src/app/api/chat/agentRuntime.ts index 169559804bdc..f5601ab2b911 100644 --- a/src/app/api/chat/agentRuntime.ts +++ b/src/app/api/chat/agentRuntime.ts @@ -165,12 +165,13 @@ const getLlmOptionsFromPayload = (provider: string, payload: JWTPayload) => { return { apiKey }; } - case ModelProvider.Stepfun: { - const { STEPFUN_API_KEY } = getLLMConfig(); + case ModelProvider.Cloudflare: { + const { CF_API_KEY, CF_ACCOUNT_ID } = getLLMConfig(); - const apiKey = apiKeyManager.pick(payload?.apiKey || STEPFUN_API_KEY); + const apiKey = apiKeyManager.pick(payload?.apiKey || CF_API_KEY); + const accountID = CF_ACCOUNT_ID; - return { apiKey }; + return { apiKey, accountID }; } } }; diff --git a/src/config/llm.ts b/src/config/llm.ts index 6cb23521a50f..0b932fe325dd 100644 --- a/src/config/llm.ts +++ b/src/config/llm.ts @@ -120,6 +120,9 @@ export const getLLMConfig = () => { ENABLED_STEPFUN: z.boolean(), STEPFUN_API_KEY: z.string().optional(), + + ENABLED_CF: z.boolean(), + CF_API_KEY: z.string().optional(), }, runtimeEnv: { API_KEY_SELECT_MODE: process.env.API_KEY_SELECT_MODE, @@ -194,6 +197,10 @@ export const getLLMConfig = () => { ENABLED_STEPFUN: !!process.env.STEPFUN_API_KEY, STEPFUN_API_KEY: process.env.STEPFUN_API_KEY, + + ENABLED_CF: !!process.env.CF_API_KEY && !!process.env.CF_ACCOUNT_ID, + CF_API_KEY: process.env.CF_API_KEY, + CF_ACCOUNT_ID: process.env.CF_ACCOUNT_ID, }, }); }; diff --git a/src/config/modelProviders/cloudflare.ts b/src/config/modelProviders/cloudflare.ts new file mode 100644 index 000000000000..9d3ba348bde6 --- /dev/null +++ b/src/config/modelProviders/cloudflare.ts @@ -0,0 +1,20 @@ +import { ModelProviderCard } from '@/types/llm'; + +// ref https://developers.cloudflare.com/workers-ai/models/#text-generation +// api https://developers.cloudflare.com/workers-ai/configuration/open-ai-compatibility +const Cloudflare: ModelProviderCard = { + chatModels: [ + { + displayName: 'LLaMA2-7B-chat', + enabled: true, + // functionCall: true, + id: '@cf/meta/llama-2-7b-chat-fp16', + tokens: 3072, + }, + ], + checkModel: '@cf/meta/llama-2-7b-chat-fp16', + id: 'cloudflare', + name: 'Cloudflare Workers AI', +}; + +export default Cloudflare; diff --git a/src/config/modelProviders/index.ts b/src/config/modelProviders/index.ts index 4f61d4b0e0e5..7cf478b502ea 100644 --- a/src/config/modelProviders/index.ts +++ b/src/config/modelProviders/index.ts @@ -3,6 +3,7 @@ import { ChatModelCard, ModelProviderCard } from '@/types/llm'; import AnthropicProvider from './anthropic'; import AzureProvider from './azure'; import BedrockProvider from './bedrock'; +import CloudflareProvider from './cloudflare'; import DeepSeekProvider from './deepseek'; import GoogleProvider from './google'; import GroqProvider from './groq'; @@ -37,6 +38,7 @@ export const LOBE_DEFAULT_MODEL_LIST: ChatModelCard[] = [ AnthropicProvider.chatModels, ZeroOneProvider.chatModels, StepfunProvider.chatModels, + CloudflareProvider.chatModels, ].flat(); export const DEFAULT_MODEL_PROVIDER_LIST = [ @@ -58,6 +60,7 @@ export const DEFAULT_MODEL_PROVIDER_LIST = [ ZeroOneProvider, ZhiPuProvider, StepfunProvider, + CloudflareProvider, ]; export const filterEnabledModels = (provider: ModelProviderCard) => { @@ -67,6 +70,7 @@ export const filterEnabledModels = (provider: ModelProviderCard) => { export { default as AnthropicProviderCard } from './anthropic'; export { default as AzureProviderCard } from './azure'; export { default as BedrockProviderCard } from './bedrock'; +export { default as CloudflareProviderCard } from './cloudflare'; export { default as DeepSeekProviderCard } from './deepseek'; export { default as GoogleProviderCard } from './google'; export { default as GroqProviderCard } from './groq'; diff --git a/src/const/settings/llm.ts b/src/const/settings/llm.ts index f468b2cb7066..90a8e7bf62fb 100644 --- a/src/const/settings/llm.ts +++ b/src/const/settings/llm.ts @@ -1,6 +1,7 @@ import { AnthropicProviderCard, BedrockProviderCard, + CloudflareProviderCard DeepSeekProviderCard, GoogleProviderCard, GroqProviderCard, @@ -33,6 +34,10 @@ export const DEFAULT_LLM_CONFIG: UserModelProviderConfig = { enabled: false, enabledModels: filterEnabledModels(BedrockProviderCard), }, + cloudflare: { + enabled: false, + enabledModels: filterEnabledModels(CloudflareProviderCard), + }, deepseek: { enabled: false, enabledModels: filterEnabledModels(DeepSeekProviderCard), diff --git a/src/libs/agent-runtime/AgentRuntime.ts b/src/libs/agent-runtime/AgentRuntime.ts index 4ee26dbb7db7..f986717c3e02 100644 --- a/src/libs/agent-runtime/AgentRuntime.ts +++ b/src/libs/agent-runtime/AgentRuntime.ts @@ -6,6 +6,7 @@ import { LobeRuntimeAI } from './BaseAI'; import { LobeAnthropicAI } from './anthropic'; import { LobeAzureOpenAI } from './azureOpenai'; import { LobeBedrockAI, LobeBedrockAIParams } from './bedrock'; +import { LobeCloudflareAI } from './cloudflare'; import { LobeDeepSeekAI } from './deepseek'; import { LobeGoogleAI } from './google'; import { LobeGroq } from './groq'; @@ -104,6 +105,7 @@ class AgentRuntime { anthropic: Partial; azure: { apiVersion?: string; apikey?: string; endpoint?: string }; bedrock: Partial; + cloudflare: Partial; deepseek: Partial; google: { apiKey?: string; baseURL?: string }; groq: Partial; @@ -219,6 +221,10 @@ class AgentRuntime { runtimeModel = new LobeStepfunAI(params.stepfun ?? {}); break; } + + case ModelProvider.Cloudflare: { + runtimeModel = new LobeCloudflareAI(params.cloudflare ?? {}); + break; } return new AgentRuntime(runtimeModel); diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts new file mode 100644 index 000000000000..31a58eb7e6e8 --- /dev/null +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -0,0 +1,21 @@ +import { ModelProvider } from '../types'; +import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; + +export interface LobeCloudflareParams { + apiKey?: string; + accountID?: string; + } + +export const LobeCloudflareAI = LobeOpenAICompatibleFactory({ + baseURL: `https://api.cloudflare.com/client/v4/accounts/${process.env.CF_ACCOUNT_ID}/ai/v1`, + chatCompletion: { + handlePayload: (payload) => ({ + ...payload, + stream: true, + }), + }, + debug: { + chatCompletion: () => process.env.DEBUG_CF_CHAT_COMPLETION === '1', + }, + provider: ModelProvider.Cloudflare, +}); \ No newline at end of file diff --git a/src/libs/agent-runtime/types/type.ts b/src/libs/agent-runtime/types/type.ts index bd5feef94b88..44ffba3a9519 100644 --- a/src/libs/agent-runtime/types/type.ts +++ b/src/libs/agent-runtime/types/type.ts @@ -25,6 +25,7 @@ export enum ModelProvider { Anthropic = 'anthropic', Azure = 'azure', Bedrock = 'bedrock', + Cloudflare = 'cloudflare', DeepSeek = 'deepseek', Google = 'google', Groq = 'groq', diff --git a/src/server/globalConfig/index.ts b/src/server/globalConfig/index.ts index 614e5083cc34..89bd294f84c7 100644 --- a/src/server/globalConfig/index.ts +++ b/src/server/globalConfig/index.ts @@ -34,6 +34,7 @@ export const getServerGlobalConfig = () => { ENABLED_MISTRAL, ENABLED_QWEN, ENABLED_STEPFUN, + ENABLED_CF, ENABLED_AZURE_OPENAI, AZURE_MODEL_LIST, @@ -71,6 +72,7 @@ export const getServerGlobalConfig = () => { }), }, bedrock: { enabled: ENABLED_AWS_BEDROCK }, + cloudflare: { enabled: ENABLED_CF }, deepseek: { enabled: ENABLED_DEEPSEEK }, google: { enabled: ENABLED_GOOGLE }, groq: { enabled: ENABLED_GROQ }, diff --git a/src/types/user/settings/keyVaults.ts b/src/types/user/settings/keyVaults.ts index 117254f2b511..b276ab2faae3 100644 --- a/src/types/user/settings/keyVaults.ts +++ b/src/types/user/settings/keyVaults.ts @@ -15,10 +15,16 @@ export interface AWSBedrockKeyVault { secretAccessKey?: string; } +export interface CloudflareKeyVault { + apiKey?: string; + accountID?: string; +} + export interface UserKeyVaults { anthropic?: OpenAICompatibleKeyVault; azure?: AzureOpenAIKeyVault; bedrock?: AWSBedrockKeyVault; + cloudflare?: CloudflareKeyVault; deepseek?: OpenAICompatibleKeyVault; google?: OpenAICompatibleKeyVault; groq?: OpenAICompatibleKeyVault; From b7745490f9696797645466b148f5203705b1cbf3 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 15:22:10 +0800 Subject: [PATCH 03/38] fix --- src/const/settings/llm.ts | 2 +- src/libs/agent-runtime/AgentRuntime.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/const/settings/llm.ts b/src/const/settings/llm.ts index 90a8e7bf62fb..150ab3756544 100644 --- a/src/const/settings/llm.ts +++ b/src/const/settings/llm.ts @@ -1,7 +1,7 @@ import { AnthropicProviderCard, BedrockProviderCard, - CloudflareProviderCard + CloudflareProviderCard, DeepSeekProviderCard, GoogleProviderCard, GroqProviderCard, diff --git a/src/libs/agent-runtime/AgentRuntime.ts b/src/libs/agent-runtime/AgentRuntime.ts index f986717c3e02..853fc6f2ad90 100644 --- a/src/libs/agent-runtime/AgentRuntime.ts +++ b/src/libs/agent-runtime/AgentRuntime.ts @@ -226,7 +226,7 @@ class AgentRuntime { runtimeModel = new LobeCloudflareAI(params.cloudflare ?? {}); break; } - + } return new AgentRuntime(runtimeModel); } } From 1336aae449e87adb59f8598eb874c467f68ee9c2 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 15:27:43 +0800 Subject: [PATCH 04/38] fix --- src/libs/agent-runtime/AgentRuntime.ts | 2 +- src/libs/agent-runtime/cloudflare/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/agent-runtime/AgentRuntime.ts b/src/libs/agent-runtime/AgentRuntime.ts index 853fc6f2ad90..7d0aa4e8c99b 100644 --- a/src/libs/agent-runtime/AgentRuntime.ts +++ b/src/libs/agent-runtime/AgentRuntime.ts @@ -6,7 +6,7 @@ import { LobeRuntimeAI } from './BaseAI'; import { LobeAnthropicAI } from './anthropic'; import { LobeAzureOpenAI } from './azureOpenai'; import { LobeBedrockAI, LobeBedrockAIParams } from './bedrock'; -import { LobeCloudflareAI } from './cloudflare'; +import { LobeCloudflareAI, LobeCloudflareParams } from './cloudflare'; import { LobeDeepSeekAI } from './deepseek'; import { LobeGoogleAI } from './google'; import { LobeGroq } from './groq'; diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index 31a58eb7e6e8..7a8207ade239 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -2,8 +2,8 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; export interface LobeCloudflareParams { - apiKey?: string; accountID?: string; + apiKey?: string; } export const LobeCloudflareAI = LobeOpenAICompatibleFactory({ From ff5361ed053efbb263558ad5a229edafbde3b347 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 15:33:30 +0800 Subject: [PATCH 05/38] fix --- src/app/api/chat/agentRuntime.ts | 2 +- src/types/user/settings/keyVaults.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/api/chat/agentRuntime.ts b/src/app/api/chat/agentRuntime.ts index f5601ab2b911..ff3152267385 100644 --- a/src/app/api/chat/agentRuntime.ts +++ b/src/app/api/chat/agentRuntime.ts @@ -171,7 +171,7 @@ const getLlmOptionsFromPayload = (provider: string, payload: JWTPayload) => { const apiKey = apiKeyManager.pick(payload?.apiKey || CF_API_KEY); const accountID = CF_ACCOUNT_ID; - return { apiKey, accountID }; + return { accountID, apiKey }; } } }; diff --git a/src/types/user/settings/keyVaults.ts b/src/types/user/settings/keyVaults.ts index b276ab2faae3..3cd373a00388 100644 --- a/src/types/user/settings/keyVaults.ts +++ b/src/types/user/settings/keyVaults.ts @@ -16,8 +16,8 @@ export interface AWSBedrockKeyVault { } export interface CloudflareKeyVault { - apiKey?: string; accountID?: string; + apiKey?: string; } export interface UserKeyVaults { From 6d658bd7214faaa5775f382a51348758ad5f307e Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 15:50:31 +0800 Subject: [PATCH 06/38] fix --- src/app/(main)/settings/llm/ProviderList/providers.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/(main)/settings/llm/ProviderList/providers.tsx b/src/app/(main)/settings/llm/ProviderList/providers.tsx index fbec7d42ed84..6382148d9277 100644 --- a/src/app/(main)/settings/llm/ProviderList/providers.tsx +++ b/src/app/(main)/settings/llm/ProviderList/providers.tsx @@ -76,7 +76,7 @@ const GoogleBrand = () => ( const CloudflareBrand = () => ( - + From 5a0a4da21d2fd15c21d5533e93e33cd3583b036f Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 16:03:41 +0800 Subject: [PATCH 07/38] fix --- src/config/llm.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/config/llm.ts b/src/config/llm.ts index 0b932fe325dd..af4060d0ad47 100644 --- a/src/config/llm.ts +++ b/src/config/llm.ts @@ -123,6 +123,7 @@ export const getLLMConfig = () => { ENABLED_CF: z.boolean(), CF_API_KEY: z.string().optional(), + CF_ACCOUNT_ID: z.string().optional(), }, runtimeEnv: { API_KEY_SELECT_MODE: process.env.API_KEY_SELECT_MODE, From 36086594cab9ea2c8c80879d159dc9756a87bd1b Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 16:22:52 +0800 Subject: [PATCH 08/38] fix --- src/libs/agent-runtime/cloudflare/index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index 7a8207ade239..21d3ccfe889f 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -11,6 +11,10 @@ export const LobeCloudflareAI = LobeOpenAICompatibleFactory({ chatCompletion: { handlePayload: (payload) => ({ ...payload, + messages: payload.messages.map(message => ({ + ...message, + role: 'assistant' as const, + })), stream: true, }), }, From 161af46f83cc306cb93ce3c83492257d96587346 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 16:39:06 +0800 Subject: [PATCH 09/38] fix --- src/libs/agent-runtime/cloudflare/index.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index 21d3ccfe889f..1abcce701111 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -8,16 +8,16 @@ export interface LobeCloudflareParams { export const LobeCloudflareAI = LobeOpenAICompatibleFactory({ baseURL: `https://api.cloudflare.com/client/v4/accounts/${process.env.CF_ACCOUNT_ID}/ai/v1`, - chatCompletion: { - handlePayload: (payload) => ({ - ...payload, - messages: payload.messages.map(message => ({ - ...message, - role: 'assistant' as const, - })), - stream: true, - }), - }, +// chatCompletion: { +// handlePayload: (payload) => ({ +// ...payload, +// messages: payload.messages.map(message => ({ +// ...message, +// role: 'assistant' as const, +// })), +// stream: true, +// }), +// }, debug: { chatCompletion: () => process.env.DEBUG_CF_CHAT_COMPLETION === '1', }, From aa609afda2858428b629f882f89b7bc3ecb7f219 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 16:51:20 +0800 Subject: [PATCH 10/38] fix icon --- src/components/ModelProviderIcon/index.tsx | 5 +++++ src/config/modelProviders/cloudflare.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/ModelProviderIcon/index.tsx b/src/components/ModelProviderIcon/index.tsx index a0f2c181e4e4..79d814d611c4 100644 --- a/src/components/ModelProviderIcon/index.tsx +++ b/src/components/ModelProviderIcon/index.tsx @@ -2,6 +2,7 @@ import { Anthropic, Azure, Bedrock, + Cloudflare, DeepSeek, Google, Groq, @@ -114,6 +115,10 @@ const ModelProviderIcon = memo(({ provider }) => { return ; } + case ModelProvider.Cloudflare: { + return ; + } + default: { return null; } diff --git a/src/config/modelProviders/cloudflare.ts b/src/config/modelProviders/cloudflare.ts index 9d3ba348bde6..9328c77c7bbd 100644 --- a/src/config/modelProviders/cloudflare.ts +++ b/src/config/modelProviders/cloudflare.ts @@ -14,7 +14,7 @@ const Cloudflare: ModelProviderCard = { ], checkModel: '@cf/meta/llama-2-7b-chat-fp16', id: 'cloudflare', - name: 'Cloudflare Workers AI', + name: 'Cloudflare', }; export default Cloudflare; From 0972e11bc43803dff1b893bbfb20f6c194b55da4 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 16:56:49 +0800 Subject: [PATCH 11/38] fix --- src/config/modelProviders/.nvmrc | 1 + src/config/modelProviders/cloudflare.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 src/config/modelProviders/.nvmrc diff --git a/src/config/modelProviders/.nvmrc b/src/config/modelProviders/.nvmrc new file mode 100644 index 000000000000..c32828c2c204 --- /dev/null +++ b/src/config/modelProviders/.nvmrc @@ -0,0 +1 @@ +lts/hydrogen \ No newline at end of file diff --git a/src/config/modelProviders/cloudflare.ts b/src/config/modelProviders/cloudflare.ts index 9328c77c7bbd..9d3ba348bde6 100644 --- a/src/config/modelProviders/cloudflare.ts +++ b/src/config/modelProviders/cloudflare.ts @@ -14,7 +14,7 @@ const Cloudflare: ModelProviderCard = { ], checkModel: '@cf/meta/llama-2-7b-chat-fp16', id: 'cloudflare', - name: 'Cloudflare', + name: 'Cloudflare Workers AI', }; export default Cloudflare; From 8ad1100d6ff3672f50488b642522953a801076b5 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 17:02:35 +0800 Subject: [PATCH 12/38] Create .nvmrc --- .nvmrc | 1 + 1 file changed, 1 insertion(+) create mode 100644 .nvmrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000000..a77793ecc520 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +lts/hydrogen From ed2f3c05f4bb5ec6e1b51105397d151321848a02 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 17:03:25 +0800 Subject: [PATCH 13/38] Delete src/config/modelProviders/.nvmrc --- src/config/modelProviders/.nvmrc | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/config/modelProviders/.nvmrc diff --git a/src/config/modelProviders/.nvmrc b/src/config/modelProviders/.nvmrc deleted file mode 100644 index c32828c2c204..000000000000 --- a/src/config/modelProviders/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -lts/hydrogen \ No newline at end of file From e47aee5ef2ee6ac72aa285f2b8a2d69e24ef5077 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 18:46:40 +0800 Subject: [PATCH 14/38] CF -> CLOUDFLARE --- src/app/api/chat/agentRuntime.ts | 6 +++--- src/config/llm.ts | 12 ++++++------ src/libs/agent-runtime/cloudflare/index.ts | 14 ++------------ src/server/globalConfig/index.ts | 4 ++-- 4 files changed, 13 insertions(+), 23 deletions(-) diff --git a/src/app/api/chat/agentRuntime.ts b/src/app/api/chat/agentRuntime.ts index ff3152267385..b2cad2097c68 100644 --- a/src/app/api/chat/agentRuntime.ts +++ b/src/app/api/chat/agentRuntime.ts @@ -166,10 +166,10 @@ const getLlmOptionsFromPayload = (provider: string, payload: JWTPayload) => { return { apiKey }; } case ModelProvider.Cloudflare: { - const { CF_API_KEY, CF_ACCOUNT_ID } = getLLMConfig(); + const { CLOUDFLARE_API_KEY, CLOUDFLARE_ACCOUNT_ID } = getLLMConfig(); - const apiKey = apiKeyManager.pick(payload?.apiKey || CF_API_KEY); - const accountID = CF_ACCOUNT_ID; + const apiKey = apiKeyManager.pick(payload?.apiKey || CLOUDFLARE_API_KEY); + const accountID = CLOUDFLARE_ACCOUNT_ID; return { accountID, apiKey }; } diff --git a/src/config/llm.ts b/src/config/llm.ts index af4060d0ad47..17fb5663d95b 100644 --- a/src/config/llm.ts +++ b/src/config/llm.ts @@ -121,9 +121,9 @@ export const getLLMConfig = () => { ENABLED_STEPFUN: z.boolean(), STEPFUN_API_KEY: z.string().optional(), - ENABLED_CF: z.boolean(), - CF_API_KEY: z.string().optional(), - CF_ACCOUNT_ID: z.string().optional(), + ENABLED_CLOUDFLARE: z.boolean(), + CLOUDFLARE_API_KEY: z.string().optional(), + CLOUDFLARE_ACCOUNT_ID: z.string().optional(), }, runtimeEnv: { API_KEY_SELECT_MODE: process.env.API_KEY_SELECT_MODE, @@ -199,9 +199,9 @@ export const getLLMConfig = () => { ENABLED_STEPFUN: !!process.env.STEPFUN_API_KEY, STEPFUN_API_KEY: process.env.STEPFUN_API_KEY, - ENABLED_CF: !!process.env.CF_API_KEY && !!process.env.CF_ACCOUNT_ID, - CF_API_KEY: process.env.CF_API_KEY, - CF_ACCOUNT_ID: process.env.CF_ACCOUNT_ID, + ENABLED_CLOUDFLARE: !!process.env.CLOUDFLARE_API_KEY && !!process.env.CLOUDFLARE_ACCOUNT_ID, + CLOUDFLARE_API_KEY: process.env.CLOUDFLARE_API_KEY, + CLOUDFLARE_ACCOUNT_ID: process.env.CLOUDFLARE_ACCOUNT_ID, }, }); }; diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index 1abcce701111..0bd3d00b6b3b 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -7,19 +7,9 @@ export interface LobeCloudflareParams { } export const LobeCloudflareAI = LobeOpenAICompatibleFactory({ - baseURL: `https://api.cloudflare.com/client/v4/accounts/${process.env.CF_ACCOUNT_ID}/ai/v1`, -// chatCompletion: { -// handlePayload: (payload) => ({ -// ...payload, -// messages: payload.messages.map(message => ({ -// ...message, -// role: 'assistant' as const, -// })), -// stream: true, -// }), -// }, + baseURL: `https://api.cloudflare.com/client/v4/accounts/${process.env.CLOUDFLARE_ACCOUNT_ID}/ai/v1`, debug: { - chatCompletion: () => process.env.DEBUG_CF_CHAT_COMPLETION === '1', + chatCompletion: () => process.env.DEBUG_CLOUDFLARE_CHAT_COMPLETION === '1', }, provider: ModelProvider.Cloudflare, }); \ No newline at end of file diff --git a/src/server/globalConfig/index.ts b/src/server/globalConfig/index.ts index 89bd294f84c7..92dd42fce4c4 100644 --- a/src/server/globalConfig/index.ts +++ b/src/server/globalConfig/index.ts @@ -34,7 +34,7 @@ export const getServerGlobalConfig = () => { ENABLED_MISTRAL, ENABLED_QWEN, ENABLED_STEPFUN, - ENABLED_CF, + ENABLED_CLOUDFLARE, ENABLED_AZURE_OPENAI, AZURE_MODEL_LIST, @@ -72,7 +72,7 @@ export const getServerGlobalConfig = () => { }), }, bedrock: { enabled: ENABLED_AWS_BEDROCK }, - cloudflare: { enabled: ENABLED_CF }, + cloudflare: { enabled: ENABLED_CLOUDFLARE }, deepseek: { enabled: ENABLED_DEEPSEEK }, google: { enabled: ENABLED_GOOGLE }, groq: { enabled: ENABLED_GROQ }, From 5a1180cc2927c218f30bf5d8a5b778cd77ebde99 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 19:31:01 +0800 Subject: [PATCH 15/38] revert --- .../settings/llm/ProviderList/providers.tsx | 46 +++++++++++++++++-- src/app/api/chat/agentRuntime.ts | 9 +++- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/app/(main)/settings/llm/ProviderList/providers.tsx b/src/app/(main)/settings/llm/ProviderList/providers.tsx index 6382148d9277..254cacefc923 100644 --- a/src/app/(main)/settings/llm/ProviderList/providers.tsx +++ b/src/app/(main)/settings/llm/ProviderList/providers.tsx @@ -11,6 +11,7 @@ import { Moonshot, OpenRouter, Perplexity, + Stepfun, Together, Tongyi, WorkersAI, @@ -21,6 +22,7 @@ import { Divider } from 'antd'; import { useTheme } from 'antd-style'; import { useMemo } from 'react'; import { Flexbox } from 'react-layout-kit'; +import urlJoin from 'url-join'; import { AnthropicProviderCard, @@ -34,6 +36,7 @@ import { OpenRouterProviderCard, PerplexityProviderCard, QwenProviderCard, + StepfunProviderCard, TogetherAIProviderCard, ZeroOneProviderCard, ZhiPuProviderCard, @@ -45,6 +48,8 @@ import { useBedrockProvider } from './Bedrock'; import { useOllamaProvider } from './Ollama'; import { useOpenAIProvider } from './OpenAI'; +const BASE_DOC_URL = 'https://lobehub.com/docs/usage/providers'; + const AnthropicBrand = () => { const { isDarkMode } = useTheme(); return ; @@ -90,67 +95,98 @@ export const useProviderList = (): ProviderItem[] => { return useMemo( () => [ - openAIProvider, - ollamaProvider, - azureProvider, + { + ...openAIProvider, + docUrl: urlJoin(BASE_DOC_URL, 'openai'), + }, + { + ...ollamaProvider, + docUrl: urlJoin(BASE_DOC_URL, 'ollama'), + }, + { + ...azureProvider, + docUrl: urlJoin(BASE_DOC_URL, 'azure'), + }, { ...GoogleProviderCard, + docUrl: urlJoin(BASE_DOC_URL, 'gemini'), title: , }, { ...AnthropicProviderCard, + docUrl: urlJoin(BASE_DOC_URL, 'anthropic'), title: , }, - bedrockProvider, + { + ...bedrockProvider, + docUrl: urlJoin(BASE_DOC_URL, 'bedrock'), + }, { ...GroqProviderCard, + docUrl: urlJoin(BASE_DOC_URL, 'groq'), title: , }, { ...OpenRouterProviderCard, + docUrl: urlJoin(BASE_DOC_URL, 'openrouter'), title: , }, { ...TogetherAIProviderCard, + docUrl: urlJoin(BASE_DOC_URL, 'togetherai'), title: , }, { ...QwenProviderCard, + docUrl: urlJoin(BASE_DOC_URL, 'qwen'), title: , }, { ...DeepSeekProviderCard, + docUrl: urlJoin(BASE_DOC_URL, 'deepseek'), title: , }, { ...MinimaxProviderCard, + docUrl: urlJoin(BASE_DOC_URL, 'minimax'), title: , }, { ...MistralProviderCard, + docUrl: urlJoin(BASE_DOC_URL, 'mistral'), title: , }, { ...MoonshotProviderCard, + docUrl: urlJoin(BASE_DOC_URL, 'moonshot'), title: , }, { ...PerplexityProviderCard, + docUrl: urlJoin(BASE_DOC_URL, 'perplexity'), title: , }, { ...ZhiPuProviderCard, + docUrl: urlJoin(BASE_DOC_URL, 'zhipu'), title: , }, { ...ZeroOneProviderCard, + docUrl: urlJoin(BASE_DOC_URL, '01ai'), title: , }, + { + ...StepfunProviderCard, + docUrl: urlJoin(BASE_DOC_URL, 'stepfun'), + title: , + }, { ...CloudflareProviderCard, + docUrl: urlJoin(BASE_DOC_URL, 'cloudflare'), title: , }, ], [azureProvider, ollamaProvider, ollamaProvider, bedrockProvider], ); -}; +}; \ No newline at end of file diff --git a/src/app/api/chat/agentRuntime.ts b/src/app/api/chat/agentRuntime.ts index b2cad2097c68..6e24ce76b593 100644 --- a/src/app/api/chat/agentRuntime.ts +++ b/src/app/api/chat/agentRuntime.ts @@ -165,13 +165,20 @@ const getLlmOptionsFromPayload = (provider: string, payload: JWTPayload) => { return { apiKey }; } + case ModelProvider.Stepfun: { + const { STEPFUN_API_KEY } = getLLMConfig(); + + const apiKey = apiKeyManager.pick(payload?.apiKey || STEPFUN_API_KEY); + + return { apiKey }; + } case ModelProvider.Cloudflare: { const { CLOUDFLARE_API_KEY, CLOUDFLARE_ACCOUNT_ID } = getLLMConfig(); const apiKey = apiKeyManager.pick(payload?.apiKey || CLOUDFLARE_API_KEY); const accountID = CLOUDFLARE_ACCOUNT_ID; - return { accountID, apiKey }; + return { accountID, apiKey }; } } }; From 7648bdebd1665cec92b14a500aba8bc65acaf5dd Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 20:06:20 +0800 Subject: [PATCH 16/38] chore: Update agentRuntime.ts and auth.ts to support Cloudflare account ID in payload --- src/app/api/chat/agentRuntime.ts | 2 +- src/const/auth.ts | 2 ++ src/libs/agent-runtime/cloudflare/index.ts | 3 ++- src/services/_auth.ts | 9 +++++++++ src/store/user/slices/modelList/selectors/keyVaults.ts | 2 ++ src/store/user/slices/modelList/selectors/modelConfig.ts | 2 ++ 6 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/app/api/chat/agentRuntime.ts b/src/app/api/chat/agentRuntime.ts index 6e24ce76b593..709b2bf2b862 100644 --- a/src/app/api/chat/agentRuntime.ts +++ b/src/app/api/chat/agentRuntime.ts @@ -176,7 +176,7 @@ const getLlmOptionsFromPayload = (provider: string, payload: JWTPayload) => { const { CLOUDFLARE_API_KEY, CLOUDFLARE_ACCOUNT_ID } = getLLMConfig(); const apiKey = apiKeyManager.pick(payload?.apiKey || CLOUDFLARE_API_KEY); - const accountID = CLOUDFLARE_ACCOUNT_ID; + const accountID = payload.apiKey && payload.cloudflareAccountID ? payload.cloudflareAccountID : CLOUDFLARE_ACCOUNT_ID; return { accountID, apiKey }; } diff --git a/src/const/auth.ts b/src/const/auth.ts index 1c0fd878dd35..7b52a8374ea0 100644 --- a/src/const/auth.ts +++ b/src/const/auth.ts @@ -35,6 +35,8 @@ export interface JWTPayload { awsAccessKeyId?: string; awsRegion?: string; awsSecretAccessKey?: string; + + cloudflareAccountID?: string; /** * user id * in client db mode it's a uuid diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index 0bd3d00b6b3b..0b581df0a8ca 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -1,5 +1,6 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; +import { llmEnv } from '@/config/llm'; export interface LobeCloudflareParams { accountID?: string; @@ -7,7 +8,7 @@ export interface LobeCloudflareParams { } export const LobeCloudflareAI = LobeOpenAICompatibleFactory({ - baseURL: `https://api.cloudflare.com/client/v4/accounts/${process.env.CLOUDFLARE_ACCOUNT_ID}/ai/v1`, + baseURL: `https://api.cloudflare.com/client/v4/accounts/${llmEnv.runtimeEnv.CLOUDFLARE_ACCOUNT_ID}/ai/v1`, debug: { chatCompletion: () => process.env.DEBUG_CLOUDFLARE_CHAT_COMPLETION === '1', }, diff --git a/src/services/_auth.ts b/src/services/_auth.ts index 6e8c98b04d9f..9e92050fec6d 100644 --- a/src/services/_auth.ts +++ b/src/services/_auth.ts @@ -36,6 +36,15 @@ export const getProviderAuthPayload = (provider: string) => { return { endpoint: config?.baseURL }; } + case ModelProvider.Cloudflare: { + const config = keyVaultsConfigSelectors.cloudflareConfig(useUserStore.getState()); + + return { + cloudflareAccountID: config?.accountID, + apiKey: config?.apiKey, + }; + } + default: { const config = keyVaultsConfigSelectors.getVaultByProvider(provider as GlobalLLMProviderKey)( useUserStore.getState(), diff --git a/src/store/user/slices/modelList/selectors/keyVaults.ts b/src/store/user/slices/modelList/selectors/keyVaults.ts index 0a9bbb265b65..a564cfde4117 100644 --- a/src/store/user/slices/modelList/selectors/keyVaults.ts +++ b/src/store/user/slices/modelList/selectors/keyVaults.ts @@ -16,6 +16,7 @@ const openAIConfig = (s: UserStore) => keyVaultsSettings(s).openai || {}; const bedrockConfig = (s: UserStore) => keyVaultsSettings(s).bedrock || {}; const ollamaConfig = (s: UserStore) => keyVaultsSettings(s).ollama || {}; const azureConfig = (s: UserStore) => keyVaultsSettings(s).azure || {}; +const cloudflareConfig = (s: UserStore) => keyVaultsSettings(s).cloudflare || {}; const getVaultByProvider = (provider: GlobalLLMProviderKey) => (s: UserStore) => (keyVaultsSettings(s)[provider] || {}) as OpenAICompatibleKeyVault & AzureOpenAIKeyVault & @@ -36,6 +37,7 @@ const password = (s: UserStore) => keyVaultsSettings(s).password || ''; export const keyVaultsConfigSelectors = { azureConfig, bedrockConfig, + cloudflareConfig, getVaultByProvider, isProviderApiKeyNotEmpty, isProviderEndpointNotEmpty, diff --git a/src/store/user/slices/modelList/selectors/modelConfig.ts b/src/store/user/slices/modelList/selectors/modelConfig.ts index d6e6fdf50215..f38d1fbf5552 100644 --- a/src/store/user/slices/modelList/selectors/modelConfig.ts +++ b/src/store/user/slices/modelList/selectors/modelConfig.ts @@ -65,12 +65,14 @@ const openAIConfig = (s: UserStore) => currentLLMSettings(s).openai; const bedrockConfig = (s: UserStore) => currentLLMSettings(s).bedrock; const ollamaConfig = (s: UserStore) => currentLLMSettings(s).ollama; const azureConfig = (s: UserStore) => currentLLMSettings(s).azure; +const cloudflareConfig = (s: UserStore) => currentLLMSettings(s).cloudflare; const isAzureEnabled = (s: UserStore) => currentLLMSettings(s).azure.enabled; export const modelConfigSelectors = { azureConfig, bedrockConfig, + cloudflareConfig, currentEditingCustomModelCard, getCustomModelCard, From 9d036eeb9e1650fd10074c8e9ef32184f1e6599d Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 20:42:29 +0800 Subject: [PATCH 17/38] Add provider setting --- .../llm/ProviderList/Cloudflare/index.tsx | 46 +++++++++++++++++++ .../settings/llm/ProviderList/providers.tsx | 10 ++-- src/locales/default/modelProvider.ts | 12 +++++ src/services/_auth.ts | 2 +- src/services/chat.ts | 7 +++ 5 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 src/app/(main)/settings/llm/ProviderList/Cloudflare/index.tsx diff --git a/src/app/(main)/settings/llm/ProviderList/Cloudflare/index.tsx b/src/app/(main)/settings/llm/ProviderList/Cloudflare/index.tsx new file mode 100644 index 000000000000..792733c016c9 --- /dev/null +++ b/src/app/(main)/settings/llm/ProviderList/Cloudflare/index.tsx @@ -0,0 +1,46 @@ +'use client'; + +import { Input } from 'antd'; +import { useTranslation } from 'react-i18next'; + +import { CloudflareProviderCard } from '@/config/modelProviders'; +import { GlobalLLMProviderKey } from '@/types/user/settings'; + +import { KeyVaultsConfigKey } from '../../const'; +import { ProviderItem } from '../../type'; +import { CloudflareBrand } from '../providers'; + +const providerKey: GlobalLLMProviderKey = 'cloudflare'; + +export const useCloudflareProvider = (): ProviderItem => { + const { t } = useTranslation('modelProvider'); + + return { + ...CloudflareProviderCard, + apiKeyItems: [ + { + children: ( + + ), + desc: t(`${providerKey}.apiKey.desc`), + label: t(`${providerKey}.apiKey.title`), + name: [KeyVaultsConfigKey, providerKey, 'apiKey'], + }, + { + children: ( + + ), + desc: t(`${providerKey}.accountID.desc`), + label: t(`${providerKey}.accountID.title`), + name: [KeyVaultsConfigKey, providerKey, 'accountID'], + }, + ], + title: , + }; +}; diff --git a/src/app/(main)/settings/llm/ProviderList/providers.tsx b/src/app/(main)/settings/llm/ProviderList/providers.tsx index 254cacefc923..cc13dfb80d64 100644 --- a/src/app/(main)/settings/llm/ProviderList/providers.tsx +++ b/src/app/(main)/settings/llm/ProviderList/providers.tsx @@ -26,7 +26,6 @@ import urlJoin from 'url-join'; import { AnthropicProviderCard, - CloudflareProviderCard, DeepSeekProviderCard, GoogleProviderCard, GroqProviderCard, @@ -45,6 +44,7 @@ import { import { ProviderItem } from '../type'; import { useAzureProvider } from './Azure'; import { useBedrockProvider } from './Bedrock'; +import { useCloudflareProvider } from './Cloudflare'; import { useOllamaProvider } from './Ollama'; import { useOpenAIProvider } from './OpenAI'; @@ -79,7 +79,7 @@ const GoogleBrand = () => ( ); -const CloudflareBrand = () => ( +export const CloudflareBrand = () => ( @@ -92,6 +92,7 @@ export const useProviderList = (): ProviderItem[] => { const ollamaProvider = useOllamaProvider(); const openAIProvider = useOpenAIProvider(); const bedrockProvider = useBedrockProvider(); + const cloudflareProvider = useCloudflareProvider(); return useMemo( () => [ @@ -182,11 +183,10 @@ export const useProviderList = (): ProviderItem[] => { title: , }, { - ...CloudflareProviderCard, + ...cloudflareProvider, docUrl: urlJoin(BASE_DOC_URL, 'cloudflare'), - title: , }, ], - [azureProvider, ollamaProvider, ollamaProvider, bedrockProvider], + [azureProvider, ollamaProvider, ollamaProvider, bedrockProvider, cloudflareProvider], ); }; \ No newline at end of file diff --git a/src/locales/default/modelProvider.ts b/src/locales/default/modelProvider.ts index 89a222c462f7..ef5091803194 100644 --- a/src/locales/default/modelProvider.ts +++ b/src/locales/default/modelProvider.ts @@ -46,6 +46,18 @@ export default { title: '使用自定义 Bedrock 鉴权信息', }, }, + cloudflare: { + accountID: { + desc: '填入 Cloudflare 账户 ID', + placeholder: 'Cloudflare Account ID', + title: 'Cloudflare Account ID', + }, + apiKey: { + desc: '填入 Cloudflare API Key', + placeholder: 'Cloudflare API Key', + title: 'Cloudflare API Key', + }, + }, ollama: { checker: { desc: '测试代理地址是否正确填写', diff --git a/src/services/_auth.ts b/src/services/_auth.ts index 9e92050fec6d..127920b8f487 100644 --- a/src/services/_auth.ts +++ b/src/services/_auth.ts @@ -40,8 +40,8 @@ export const getProviderAuthPayload = (provider: string) => { const config = keyVaultsConfigSelectors.cloudflareConfig(useUserStore.getState()); return { - cloudflareAccountID: config?.accountID, apiKey: config?.apiKey, + cloudflareAccountID: config?.accountID, }; } diff --git a/src/services/chat.ts b/src/services/chat.ts index 3eb78b300093..8e77d74aecfc 100644 --- a/src/services/chat.ts +++ b/src/services/chat.ts @@ -154,6 +154,13 @@ export function initializeWithClientStore(provider: string, payload: any) { case ModelProvider.ZeroOne: { break; } + case ModelProvider.Cloudflare: { + providerOptions = { + accountID: providerAuthPayload?.cloudflareAccountID, + apikey: providerAuthPayload?.apiKey, + }; + break; + } } /** From 7fe94014e243fac607d9d7c674982a55e31b8992 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 21:06:03 +0800 Subject: [PATCH 18/38] fix --- src/libs/agent-runtime/cloudflare/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index 0b581df0a8ca..b1303b69e810 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -8,7 +8,7 @@ export interface LobeCloudflareParams { } export const LobeCloudflareAI = LobeOpenAICompatibleFactory({ - baseURL: `https://api.cloudflare.com/client/v4/accounts/${llmEnv.runtimeEnv.CLOUDFLARE_ACCOUNT_ID}/ai/v1`, + baseURL: `https://api.cloudflare.com/client/v4/accounts/${llmEnv.CLOUDFLARE_ACCOUNT_ID}/ai/v1`, debug: { chatCompletion: () => process.env.DEBUG_CLOUDFLARE_CHAT_COMPLETION === '1', }, From fa23ba43af2331504a9bba8105bccd562e8c0f0d Mon Sep 17 00:00:00 2001 From: sxjeru Date: Fri, 21 Jun 2024 22:49:35 +0800 Subject: [PATCH 19/38] Update cloudflare.ts --- src/config/modelProviders/cloudflare.ts | 73 +++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/src/config/modelProviders/cloudflare.ts b/src/config/modelProviders/cloudflare.ts index 9d3ba348bde6..d035b16c0cd1 100644 --- a/src/config/modelProviders/cloudflare.ts +++ b/src/config/modelProviders/cloudflare.ts @@ -5,14 +5,77 @@ import { ModelProviderCard } from '@/types/llm'; const Cloudflare: ModelProviderCard = { chatModels: [ { - displayName: 'LLaMA2-7B-chat', + displayName: 'deepseek-coder-6.7b-instruct-awq', enabled: true, - // functionCall: true, - id: '@cf/meta/llama-2-7b-chat-fp16', - tokens: 3072, + id: '@hf/thebloke/deepseek-coder-6.7b-instruct-awq', + tokens: 16384, + }, + { + displayName: 'deepseek-math-7b-instruct', + enabled: true, + id: '@hf/thebloke/deepseek-math-7b-instruct', + tokens: 4096, + }, + { + displayName: 'gemma-7b-it', + enabled: true, + id: '@hf/google/gemma-7b-it', + tokens: 2048, + }, + { + displayName: 'hermes-2-pro-mistral-7b', + enabled: true, + // functionCall: true, + id: '@hf/nousresearch/hermes-2-pro-mistral-7b', + tokens: 4096, + }, + { + displayName: 'llama-3-8b-instruct-awq', + id: '@cf/meta/llama-3-8b-instruct-awq', + tokens: 8192, + }, + { + displayName: 'mistral-7b-instruct-v0.2', + id: '@hf/mistral/mistral-7b-instruct-v0.2', + tokens: 4096, + }, + { + displayName: 'neural-chat-7b-v3-1-awq', + enabled: true, + id: '@hf/thebloke/neural-chat-7b-v3-1-awq', + tokens: 32768, + }, + { + displayName: 'openchat-3.5-0106', + id: '@cf/openchat/openchat-3.5-0106', + tokens: 8192, + }, + { + displayName: 'openhermes-2.5-mistral-7b-awq', + enabled: true, + id: '@hf/thebloke/openhermes-2.5-mistral-7b-awq', + tokens: 32768, + }, + { + displayName: 'qwen1.5-14b-chat-awq', + enabled: true, + id: '@cf/qwen/qwen1.5-14b-chat-awq', + tokens: 32768, + }, + { + displayName: 'starling-lm-7b-beta', + enabled: true, + id: '@hf/nexusflow/starling-lm-7b-beta', + tokens: 4096, + }, + { + displayName: 'zephyr-7b-beta-awq', + enabled: true, + id: '@hf/thebloke/zephyr-7b-beta-awq', + tokens: 32768, }, ], - checkModel: '@cf/meta/llama-2-7b-chat-fp16', + checkModel: '@hf/thebloke/deepseek-coder-6.7b-instruct-awq', id: 'cloudflare', name: 'Cloudflare Workers AI', }; From 44143204c1256a53dce42bdcb7f1e1db1d31fde7 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Mon, 24 Jun 2024 12:55:45 +0000 Subject: [PATCH 20/38] fix --- .env.example | 6 ++++++ src/libs/agent-runtime/cloudflare/index.ts | 12 ++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.env.example b/.env.example index f1b8bdf21794..5c25dc153d9a 100644 --- a/.env.example +++ b/.env.example @@ -112,6 +112,12 @@ OPENAI_API_KEY=sk-xxxxxxxxx # QWEN_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +### Cloudflare Workers AI #### + +# CLOUDFLARE_ACCOUNT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +# CLOUDFLARE_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx + + ######################################## ############ Market Service ############ ######################################## diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index b1303b69e810..c87caf1f2ed7 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -1,16 +1,16 @@ + import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { llmEnv } from '@/config/llm'; export interface LobeCloudflareParams { - accountID?: string; - apiKey?: string; - } + accountID?: string; + apiKey?: string; +} export const LobeCloudflareAI = LobeOpenAICompatibleFactory({ - baseURL: `https://api.cloudflare.com/client/v4/accounts/${llmEnv.CLOUDFLARE_ACCOUNT_ID}/ai/v1`, + baseURL: `https://api.cloudflare.com/client/v4/accounts/${process.env.CLOUDFLARE_ACCOUNT_ID}/ai/v1`, debug: { chatCompletion: () => process.env.DEBUG_CLOUDFLARE_CHAT_COMPLETION === '1', }, provider: ModelProvider.Cloudflare, -}); \ No newline at end of file +}); From 8d1f973df0a19b02a8463dc4e63203ae25f2d7a9 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Mon, 24 Jun 2024 23:02:02 +0800 Subject: [PATCH 21/38] Update cloudflare.ts --- src/config/modelProviders/cloudflare.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/config/modelProviders/cloudflare.ts b/src/config/modelProviders/cloudflare.ts index d035b16c0cd1..e946e9c4a194 100644 --- a/src/config/modelProviders/cloudflare.ts +++ b/src/config/modelProviders/cloudflare.ts @@ -8,7 +8,7 @@ const Cloudflare: ModelProviderCard = { displayName: 'deepseek-coder-6.7b-instruct-awq', enabled: true, id: '@hf/thebloke/deepseek-coder-6.7b-instruct-awq', - tokens: 16384, + tokens: 16_384, }, { displayName: 'deepseek-math-7b-instruct', @@ -43,7 +43,7 @@ const Cloudflare: ModelProviderCard = { displayName: 'neural-chat-7b-v3-1-awq', enabled: true, id: '@hf/thebloke/neural-chat-7b-v3-1-awq', - tokens: 32768, + tokens: 32_768, }, { displayName: 'openchat-3.5-0106', @@ -54,13 +54,13 @@ const Cloudflare: ModelProviderCard = { displayName: 'openhermes-2.5-mistral-7b-awq', enabled: true, id: '@hf/thebloke/openhermes-2.5-mistral-7b-awq', - tokens: 32768, + tokens: 32_768, }, { displayName: 'qwen1.5-14b-chat-awq', enabled: true, id: '@cf/qwen/qwen1.5-14b-chat-awq', - tokens: 32768, + tokens: 32_768, }, { displayName: 'starling-lm-7b-beta', @@ -72,7 +72,7 @@ const Cloudflare: ModelProviderCard = { displayName: 'zephyr-7b-beta-awq', enabled: true, id: '@hf/thebloke/zephyr-7b-beta-awq', - tokens: 32768, + tokens: 32_768, }, ], checkModel: '@hf/thebloke/deepseek-coder-6.7b-instruct-awq', From 7efaab978f006b8e7e5b8b2fab9290120ef38b95 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Mon, 1 Jul 2024 20:38:34 +0800 Subject: [PATCH 22/38] accountID --- src/libs/agent-runtime/AgentRuntime.ts | 6 +++++- .../agent-runtime/utils/openaiCompatibleFactory/index.ts | 8 +++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/libs/agent-runtime/AgentRuntime.ts b/src/libs/agent-runtime/AgentRuntime.ts index 7d0aa4e8c99b..1736098c4569 100644 --- a/src/libs/agent-runtime/AgentRuntime.ts +++ b/src/libs/agent-runtime/AgentRuntime.ts @@ -223,7 +223,11 @@ class AgentRuntime { } case ModelProvider.Cloudflare: { - runtimeModel = new LobeCloudflareAI(params.cloudflare ?? {}); + const cloudflareParams = params.cloudflare ?? {}; + runtimeModel = new LobeCloudflareAI({ + ...cloudflareParams, + baseURL: `https://api.cloudflare.com/client/v4/accounts/${params.cloudflare?.accountID}/ai/v1` + }); break; } } diff --git a/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts b/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts index da5e94349b01..523bc1e2ae81 100644 --- a/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts +++ b/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts @@ -28,7 +28,7 @@ const CHAT_MODELS_BLOCK_LIST = [ ]; interface OpenAICompatibleFactoryOptions { - baseURL?: string; + baseURL?: string | ((params: { cfAccountID: string }) => string); chatCompletion?: { handleError?: (error: any) => Omit | undefined; handlePayload?: (payload: ChatStreamPayload) => OpenAI.ChatCompletionCreateParamsStreaming; @@ -68,10 +68,12 @@ export const LobeOpenAICompatibleFactory = ({ baseURL: string; - constructor({ apiKey, baseURL = DEFAULT_BASE_URL, ...res }: ClientOptions) { + constructor({ apiKey, baseURL = DEFAULT_BASE_URL, cfAccountID, ...res }: ClientOptions & { cfAccountID?: string }) { if (!apiKey) throw AgentRuntimeError.createError(ErrorType?.invalidAPIKey); - this.client = new OpenAI({ apiKey, baseURL, ...constructorOptions, ...res }); + const finalBaseURL = typeof baseURL === 'function' ? baseURL({ accountId: cfAccountID ?? '' }) : baseURL; + + this.client = new OpenAI({ apiKey, baseURL: finalBaseURL, ...constructorOptions, ...res }); this.baseURL = this.client.baseURL; } From 87f0721967ea438b80986141ea44cfb020b5f202 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Mon, 1 Jul 2024 13:39:53 +0000 Subject: [PATCH 23/38] fix --- .../agent-runtime/utils/openaiCompatibleFactory/index.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts b/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts index 523bc1e2ae81..da5e94349b01 100644 --- a/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts +++ b/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts @@ -28,7 +28,7 @@ const CHAT_MODELS_BLOCK_LIST = [ ]; interface OpenAICompatibleFactoryOptions { - baseURL?: string | ((params: { cfAccountID: string }) => string); + baseURL?: string; chatCompletion?: { handleError?: (error: any) => Omit | undefined; handlePayload?: (payload: ChatStreamPayload) => OpenAI.ChatCompletionCreateParamsStreaming; @@ -68,12 +68,10 @@ export const LobeOpenAICompatibleFactory = ({ baseURL: string; - constructor({ apiKey, baseURL = DEFAULT_BASE_URL, cfAccountID, ...res }: ClientOptions & { cfAccountID?: string }) { + constructor({ apiKey, baseURL = DEFAULT_BASE_URL, ...res }: ClientOptions) { if (!apiKey) throw AgentRuntimeError.createError(ErrorType?.invalidAPIKey); - const finalBaseURL = typeof baseURL === 'function' ? baseURL({ accountId: cfAccountID ?? '' }) : baseURL; - - this.client = new OpenAI({ apiKey, baseURL: finalBaseURL, ...constructorOptions, ...res }); + this.client = new OpenAI({ apiKey, baseURL, ...constructorOptions, ...res }); this.baseURL = this.client.baseURL; } From 26de0f13e3c0bbf6f4dba15581adc24549ef4533 Mon Sep 17 00:00:00 2001 From: sxjeru Date: Mon, 1 Jul 2024 23:22:06 +0800 Subject: [PATCH 24/38] i18n --- locales/ar/modelProvider.json | 12 ++++++++++++ locales/bg-BG/modelProvider.json | 12 ++++++++++++ locales/de-DE/modelProvider.json | 12 ++++++++++++ locales/en-US/modelProvider.json | 12 ++++++++++++ locales/es-ES/modelProvider.json | 12 ++++++++++++ locales/fr-FR/modelProvider.json | 12 ++++++++++++ locales/it-IT/modelProvider.json | 12 ++++++++++++ locales/ja-JP/modelProvider.json | 12 ++++++++++++ locales/ko-KR/modelProvider.json | 12 ++++++++++++ locales/nl-NL/modelProvider.json | 12 ++++++++++++ locales/pl-PL/modelProvider.json | 12 ++++++++++++ locales/pt-BR/modelProvider.json | 12 ++++++++++++ locales/ru-RU/modelProvider.json | 12 ++++++++++++ locales/tr-TR/modelProvider.json | 12 ++++++++++++ locales/vi-VN/modelProvider.json | 12 ++++++++++++ locales/zh-CN/modelProvider.json | 12 ++++++++++++ locales/zh-TW/modelProvider.json | 12 ++++++++++++ src/locales/default/modelProvider.ts | 6 +++--- 18 files changed, 207 insertions(+), 3 deletions(-) diff --git a/locales/ar/modelProvider.json b/locales/ar/modelProvider.json index c86dcf3a884a..4247dc8af16a 100644 --- a/locales/ar/modelProvider.json +++ b/locales/ar/modelProvider.json @@ -45,6 +45,18 @@ "title": "استخدام معلومات المصادقة الخاصة بـ Bedrock المخصصة" } }, + "cloudflare": { + "accountID": { + "desc": "يرجى ملء Cloudflare Account ID", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "يرجى ملء Cloudflare API Key", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "اختبر ما إذا تم إدخال عنوان الوكيل بشكل صحيح", diff --git a/locales/bg-BG/modelProvider.json b/locales/bg-BG/modelProvider.json index 30e481a8d1f0..66ad791e5e6f 100644 --- a/locales/bg-BG/modelProvider.json +++ b/locales/bg-BG/modelProvider.json @@ -45,6 +45,18 @@ "title": "Използване на персонализирана информация за удостоверяване на Bedrock" } }, + "cloudflare": { + "accountID": { + "desc": "Моля, въведете Cloudflare Account ID", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "Моля, въведете Cloudflare API Key", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "Тестване дали адресът на прокси е попълнен правилно", diff --git a/locales/de-DE/modelProvider.json b/locales/de-DE/modelProvider.json index 1984d79d96f1..e48adf2d5502 100644 --- a/locales/de-DE/modelProvider.json +++ b/locales/de-DE/modelProvider.json @@ -45,6 +45,18 @@ "title": "Verwenden Sie benutzerdefinierte Bedrock-Authentifizierungsinformationen" } }, + "cloudflare": { + "accountID": { + "desc": "Bitte füllen Sie die Cloudflare Account ID", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "Bitte füllen Sie die Cloudflare API Key", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "Testen Sie, ob die Proxy-Adresse korrekt eingetragen wurde", diff --git a/locales/en-US/modelProvider.json b/locales/en-US/modelProvider.json index 0dca43e992ca..970d359e3bbf 100644 --- a/locales/en-US/modelProvider.json +++ b/locales/en-US/modelProvider.json @@ -45,6 +45,18 @@ "title": "Use Custom Bedrock Authentication Information" } }, + "cloudflare": { + "accountID": { + "desc": "Please enter Cloudflare Account ID", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "Please enter Cloudflare API Key", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "Test if the proxy address is correctly filled in", diff --git a/locales/es-ES/modelProvider.json b/locales/es-ES/modelProvider.json index 3f8252390ba2..eb23eb33e4a6 100644 --- a/locales/es-ES/modelProvider.json +++ b/locales/es-ES/modelProvider.json @@ -45,6 +45,18 @@ "title": "Usar información de autenticación de Bedrock personalizada" } }, + "cloudflare": { + "accountID": { + "desc": "Por favor complete la Cloudflare Account ID", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "Por favor complete la Cloudflare API Key", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "Prueba si la dirección del proxy de la interfaz se ha introducido correctamente", diff --git a/locales/fr-FR/modelProvider.json b/locales/fr-FR/modelProvider.json index 196204d65b7b..0854054c97e3 100644 --- a/locales/fr-FR/modelProvider.json +++ b/locales/fr-FR/modelProvider.json @@ -45,6 +45,18 @@ "title": "Utiliser des informations d'authentification Bedrock personnalisées" } }, + "cloudflare": { + "accountID": { + "desc": "Veuillez remplir l'Cloudflare Account ID", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "Veuillez remplir l'Cloudflare API Key", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "Vérifiez si l'adresse du proxy est correctement saisie", diff --git a/locales/it-IT/modelProvider.json b/locales/it-IT/modelProvider.json index 07810bf158db..04c5d7e1c99f 100644 --- a/locales/it-IT/modelProvider.json +++ b/locales/it-IT/modelProvider.json @@ -45,6 +45,18 @@ "title": "Usa le informazioni di autenticazione Bedrock personalizzate" } }, + "cloudflare": { + "accountID": { + "desc": "Compila l'Cloudflare Account ID", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "Compila l'Cloudflare API Key", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "Verifica se l'indirizzo del proxy è stato compilato correttamente", diff --git a/locales/ja-JP/modelProvider.json b/locales/ja-JP/modelProvider.json index d1ef2f8948b3..f8e564f0cf92 100644 --- a/locales/ja-JP/modelProvider.json +++ b/locales/ja-JP/modelProvider.json @@ -45,6 +45,18 @@ "title": "使用カスタム Bedrock 認証情報" } }, + "cloudflare": { + "accountID": { + "desc": "Cloudflare Account ID を入力してください", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "Cloudflare API Key を入力してください", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "プロキシアドレスが正しく入力されているかをテストします", diff --git a/locales/ko-KR/modelProvider.json b/locales/ko-KR/modelProvider.json index c1b96eee6ea7..55ef3c42957f 100644 --- a/locales/ko-KR/modelProvider.json +++ b/locales/ko-KR/modelProvider.json @@ -45,6 +45,18 @@ "title": "사용자 정의 Bedrock 인증 정보 사용" } }, + "cloudflare": { + "accountID": { + "desc": "Cloudflare Account ID 를 작성해 주세요.", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "Cloudflare API Key 를 작성해 주세요.", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "프록시 주소가 올바르게 입력되었는지 테스트합니다", diff --git a/locales/nl-NL/modelProvider.json b/locales/nl-NL/modelProvider.json index 9d95b27b2e9f..6d4d00003015 100644 --- a/locales/nl-NL/modelProvider.json +++ b/locales/nl-NL/modelProvider.json @@ -45,6 +45,18 @@ "title": "Gebruik aangepaste Bedrock-verificatiegegevens" } }, + "cloudflare": { + "accountID": { + "desc": "Voer Cloudflare Account ID in", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "Voer Cloudflare API Key in", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "Test of het proxyadres correct is ingevuld", diff --git a/locales/pl-PL/modelProvider.json b/locales/pl-PL/modelProvider.json index c233755bd553..2e495cd7e0f2 100644 --- a/locales/pl-PL/modelProvider.json +++ b/locales/pl-PL/modelProvider.json @@ -45,6 +45,18 @@ "title": "Użyj niestandardowych informacji uwierzytelniających Bedrock" } }, + "cloudflare": { + "accountID": { + "desc": "Wprowadź klucz Cloudflare Account ID", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "Wprowadź klucz Cloudflare API Key", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "Test czy adres proxy jest poprawnie wypełniony", diff --git a/locales/pt-BR/modelProvider.json b/locales/pt-BR/modelProvider.json index 1521fb28dd6b..cd2a437de5b8 100644 --- a/locales/pt-BR/modelProvider.json +++ b/locales/pt-BR/modelProvider.json @@ -45,6 +45,18 @@ "title": "Usar informações de autenticação Bedrock personalizadas" } }, + "cloudflare": { + "accountID": { + "desc": "Insira o Cloudflare Account ID", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "Insira o Cloudflare API Key", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "Teste se o endereço do proxy está corretamente preenchido", diff --git a/locales/ru-RU/modelProvider.json b/locales/ru-RU/modelProvider.json index d4ee8caa89e2..5c07b72dcdd3 100644 --- a/locales/ru-RU/modelProvider.json +++ b/locales/ru-RU/modelProvider.json @@ -45,6 +45,18 @@ "title": "Использовать пользовательскую информацию аутентификации Bedrock" } }, + "cloudflare": { + "accountID": { + "desc": "Пожалуйста, заполните Cloudflare Account ID", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "Пожалуйста, заполните Cloudflare API Key", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "Проверить правильность адреса прокси", diff --git a/locales/tr-TR/modelProvider.json b/locales/tr-TR/modelProvider.json index 549957a54c01..c059b28b2587 100644 --- a/locales/tr-TR/modelProvider.json +++ b/locales/tr-TR/modelProvider.json @@ -45,6 +45,18 @@ "title": "Özel Bedrock Kimlik Bilgilerini Kullan" } }, + "cloudflare": { + "accountID": { + "desc": "Lütfen doldurun Cloudflare Account ID", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "Lütfen doldurun Cloudflare API Key", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "Proxy adresinin doğru girilip girilmediğini test edin", diff --git a/locales/vi-VN/modelProvider.json b/locales/vi-VN/modelProvider.json index 890169ab2623..9da7c7ac3204 100644 --- a/locales/vi-VN/modelProvider.json +++ b/locales/vi-VN/modelProvider.json @@ -45,6 +45,18 @@ "title": "Sử dụng Thông tin Xác thực Bedrock tùy chỉnh" } }, + "cloudflare": { + "accountID": { + "desc": "Vui lòng nhập Cloudflare Account ID", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "Vui lòng nhập Cloudflare API Key", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "Kiểm tra địa chỉ proxy có được nhập chính xác không", diff --git a/locales/zh-CN/modelProvider.json b/locales/zh-CN/modelProvider.json index 6e36ee95a505..e99a88b11ccf 100644 --- a/locales/zh-CN/modelProvider.json +++ b/locales/zh-CN/modelProvider.json @@ -45,6 +45,18 @@ "title": "使用自定义 Bedrock 鉴权信息" } }, + "cloudflare": { + "accountID": { + "desc": "请填写 Cloudflare 账户 ID", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "请填写 Cloudflare API Key", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "测试代理地址是否正确填写", diff --git a/locales/zh-TW/modelProvider.json b/locales/zh-TW/modelProvider.json index 3b9baacb6b07..a9a33461ad61 100644 --- a/locales/zh-TW/modelProvider.json +++ b/locales/zh-TW/modelProvider.json @@ -45,6 +45,18 @@ "title": "使用自定義 Bedrock 驗證資訊" } }, + "cloudflare": { + "accountID": { + "desc": "請填入 Cloudflare 帳戶 ID", + "placeholder": "Cloudflare Account ID", + "title": "Cloudflare Account ID" + }, + "apiKey": { + "desc": "請填入 Cloudflare API Key", + "placeholder": "Cloudflare API Key", + "title": "Cloudflare API Key" + } + }, "ollama": { "checker": { "desc": "測試代理地址是否正確填寫", diff --git a/src/locales/default/modelProvider.ts b/src/locales/default/modelProvider.ts index ef5091803194..37abf3721dec 100644 --- a/src/locales/default/modelProvider.ts +++ b/src/locales/default/modelProvider.ts @@ -21,7 +21,7 @@ export default { }, bedrock: { accessKeyId: { - desc: '填入AWS Access Key Id', + desc: '填入 AWS Access Key Id', placeholder: 'AWS Access Key Id', title: 'AWS Access Key Id', }, @@ -48,12 +48,12 @@ export default { }, cloudflare: { accountID: { - desc: '填入 Cloudflare 账户 ID', + desc: '请填写 Cloudflare 账户 ID', placeholder: 'Cloudflare Account ID', title: 'Cloudflare Account ID', }, apiKey: { - desc: '填入 Cloudflare API Key', + desc: '请填写 Cloudflare API Key', placeholder: 'Cloudflare API Key', title: 'Cloudflare API Key', }, From e0f541a9f32f036e5334f218ed8e29046e29e3db Mon Sep 17 00:00:00 2001 From: sxjeru Date: Sat, 27 Jul 2024 12:26:01 +0800 Subject: [PATCH 25/38] Update index.ts --- src/libs/agent-runtime/baichuan/index.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libs/agent-runtime/baichuan/index.ts b/src/libs/agent-runtime/baichuan/index.ts index 07684a476297..3d5f01d3e6c5 100644 --- a/src/libs/agent-runtime/baichuan/index.ts +++ b/src/libs/agent-runtime/baichuan/index.ts @@ -22,10 +22,7 @@ export const LobeBaichuanAI = LobeOpenAICompatibleFactory({ // If between 1 and 2, keep the original value } - return { - ...rest, - frequency_penalty: adjustedFrequencyPenalty, - } as OpenAI.ChatCompletionCreateParamsStreaming; + return { ...rest, frequency_penalty: adjustedFrequencyPenalty } as OpenAI.ChatCompletionCreateParamsStreaming; }, }, debug: { From bc26fd86991ec8bbab1ef0da18b62285731290aa Mon Sep 17 00:00:00 2001 From: sxjeru Date: Sat, 27 Jul 2024 12:28:08 +0800 Subject: [PATCH 26/38] Update baichuan.ts --- src/config/modelProviders/baichuan.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/config/modelProviders/baichuan.ts b/src/config/modelProviders/baichuan.ts index 3a432bf6dcd4..12570eebdb05 100644 --- a/src/config/modelProviders/baichuan.ts +++ b/src/config/modelProviders/baichuan.ts @@ -4,8 +4,7 @@ import { ModelProviderCard } from '@/types/llm'; const Baichuan: ModelProviderCard = { chatModels: [ { - description: - '模型能力国内第一,在知识百科、长文本、生成创作等中文任务上超越国外主流模型。还具备行业领先的多模态能力,多项权威评测基准表现优异。', + description: '模型能力国内第一,在知识百科、长文本、生成创作等中文任务上超越国外主流模型。还具备行业领先的多模态能力,多项权威评测基准表现优异。', displayName: 'Baichuan 4', enabled: true, functionCall: true, @@ -14,8 +13,7 @@ const Baichuan: ModelProviderCard = { tokens: 32_768, }, { - description: - '针对企业高频场景优化,效果大幅提升,高性价比。相对于Baichuan2模型,内容创作提升20%,知识问答提升17%, 角色扮演能力提升40%。整体效果比GPT3.5更优。', + description: '针对企业高频场景优化,效果大幅提升,高性价比。相对于Baichuan2模型,内容创作提升20%,知识问答提升17%, 角色扮演能力提升40%。整体效果比GPT3.5更优。', displayName: 'Baichuan 3 Turbo', enabled: true, functionCall: true, @@ -24,8 +22,7 @@ const Baichuan: ModelProviderCard = { tokens: 32_768, }, { - description: - '具备 128K 超长上下文窗口,针对企业高频场景优化,效果大幅提升,高性价比。相对于Baichuan2模型,内容创作提升20%,知识问答提升17%, 角色扮演能力提升40%。整体效果比GPT3.5更优。', + description: '具备 128K 超长上下文窗口,针对企业高频场景优化,效果大幅提升,高性价比。相对于Baichuan2模型,内容创作提升20%,知识问答提升17%, 角色扮演能力提升40%。整体效果比GPT3.5更优。', displayName: 'Baichuan 3 Turbo 128k', enabled: true, id: 'Baichuan3-Turbo-128k', @@ -33,8 +30,7 @@ const Baichuan: ModelProviderCard = { tokens: 128_000, }, { - description: - '采用搜索增强技术实现大模型与领域知识、全网知识的全面链接。支持PDF、Word等多种文档上传及网址输入,信息获取及时、全面,输出结果准确、专业。', + description: '采用搜索增强技术实现大模型与领域知识、全网知识的全面链接。支持PDF、Word等多种文档上传及网址输入,信息获取及时、全面,输出结果准确、专业。', displayName: 'Baichuan 2 Turbo', enabled: true, id: 'Baichuan2-Turbo', @@ -42,8 +38,7 @@ const Baichuan: ModelProviderCard = { tokens: 32_768, }, { - description: - '具备 192K 超长上下文窗口,采用搜索增强技术实现大模型与领域知识、全网知识的全面链接。支持PDF、Word等多种文档上传及网址输入,信息获取及时、全面,输出结果准确、专业。', + description: '具备 192K 超长上下文窗口,采用搜索增强技术实现大模型与领域知识、全网知识的全面链接。支持PDF、Word等多种文档上传及网址输入,信息获取及时、全面,输出结果准确、专业。', displayName: 'Baichuan 2 Turbo 192k', enabled: true, id: 'Baichuan2-Turbo-192k', From bb029542fd5402f8fc3878f33fd3c9941d12b27b Mon Sep 17 00:00:00 2001 From: sxjeru Date: Sat, 27 Jul 2024 12:48:11 +0800 Subject: [PATCH 27/38] Update cloudflare.ts --- src/config/modelProviders/cloudflare.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/config/modelProviders/cloudflare.ts b/src/config/modelProviders/cloudflare.ts index e946e9c4a194..cf7acb35c2ab 100644 --- a/src/config/modelProviders/cloudflare.ts +++ b/src/config/modelProviders/cloudflare.ts @@ -34,6 +34,11 @@ const Cloudflare: ModelProviderCard = { id: '@cf/meta/llama-3-8b-instruct-awq', tokens: 8192, }, + { + displayName: 'llama-3.1-8b-instruct', + id: '@cf/meta/llama-3.1-8b-instruct', + tokens: 128_000, + }, { displayName: 'mistral-7b-instruct-v0.2', id: '@hf/mistral/mistral-7b-instruct-v0.2', From 85021aa9eabfb59316c0c59bcb749f0266502def Mon Sep 17 00:00:00 2001 From: BrandonStudio Date: Wed, 31 Jul 2024 14:57:39 +0800 Subject: [PATCH 28/38] save changes --- src/config/modelProviders/cloudflare.ts | 13 +- src/libs/agent-runtime/cloudflare/index.ts | 218 ++++++++++++++++++++- src/store/user/slices/modelList/action.ts | 4 + 3 files changed, 225 insertions(+), 10 deletions(-) diff --git a/src/config/modelProviders/cloudflare.ts b/src/config/modelProviders/cloudflare.ts index e946e9c4a194..0f53f547b84a 100644 --- a/src/config/modelProviders/cloudflare.ts +++ b/src/config/modelProviders/cloudflare.ts @@ -74,9 +74,20 @@ const Cloudflare: ModelProviderCard = { id: '@hf/thebloke/zephyr-7b-beta-awq', tokens: 32_768, }, + { + description: + 'Generation over generation, Meta Llama 3 demonstrates state-of-the-art performance on a wide range of industry benchmarks and offers new capabilities, including improved reasoning.\t', + displayName: 'meta-llama-3-8b-instruct', + enabled: true, + functionCall: false, + id: '@hf/meta-llama/meta-llama-3-8b-instruct', + }, ], - checkModel: '@hf/thebloke/deepseek-coder-6.7b-instruct-awq', + checkModel: '@hf/meta-llama/meta-llama-3-8b-instruct', id: 'cloudflare', + modelList: { + showModelFetcher: true, + }, name: 'Cloudflare Workers AI', }; diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index c87caf1f2ed7..8c546988c0a8 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -1,16 +1,216 @@ +import { ChatModelCard } from '@/types/llm'; +import { LobeRuntimeAI } from '../BaseAI'; +import { AgentRuntimeErrorType } from '../error'; +import { ChatCompetitionOptions, ChatStreamPayload, ModelProvider } from '../types'; +import { AgentRuntimeError } from '../utils/createError'; +import { desensitizeUrl } from '../utils/desensitizeUrl'; +import { StreamingResponse } from '../utils/response'; -import { ModelProvider } from '../types'; -import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; +const DEFAULT_BASE_URL_PREFIX = 'https://api.cloudflare.com'; export interface LobeCloudflareParams { accountID?: string; apiKey?: string; } -export const LobeCloudflareAI = LobeOpenAICompatibleFactory({ - baseURL: `https://api.cloudflare.com/client/v4/accounts/${process.env.CLOUDFLARE_ACCOUNT_ID}/ai/v1`, - debug: { - chatCompletion: () => process.env.DEBUG_CLOUDFLARE_CHAT_COMPLETION === '1', - }, - provider: ModelProvider.Cloudflare, -}); +function fillUrl(accountID: string): string { + return `${DEFAULT_BASE_URL_PREFIX}/client/v4/accounts/${accountID}/ai/run/`; +} + +function desensitizeAccountId(path: string): string { + return path.replace(/\/[\dA-Fa-f]{32}\//, '/****/'); +} + +function desensitizeCloudflareUrl(url: string): string { + const urlObj = new URL(url); + let { protocol, hostname, port, pathname, search } = urlObj; + if (url.startsWith(DEFAULT_BASE_URL_PREFIX)) { + return `${protocol}//${hostname}${port ? `:${port}` : ''}${desensitizeAccountId(pathname)}${search}`; + } else { + const desensitizedUrl = desensitizeUrl(`${protocol}//${hostname}${port ? `:${port}` : ''}`); + return `${desensitizedUrl}${desensitizeAccountId(pathname)}${search}`; + } +} + +const CF_PROPERTY_NAME = 'property_id'; + +function getModelBeta(model: any): boolean { + try { + const betaProperty = model['properties'].filter( + (property: any) => property[CF_PROPERTY_NAME] === 'beta', + ); + if (betaProperty.length === 1) { + return betaProperty[0]['value'].toLowerCase() === "true"; // This is a string now. + } + return false; + } catch { + return false; + } +} + +function getModelDisplayName(model: any, beta: boolean): string { + const modelId = model['name']; + let name = modelId.split('/').at(-1)!; + if (beta) { + name += ' (Beta)'; + } + return name; +} + +function getModelFunctionCalling(model: any): boolean { + try { + const fcProperty = model['properties'].filter( + (property: any) => property[CF_PROPERTY_NAME] === 'function_calling', + ); + if (fcProperty.length === 1) { + return fcProperty[0]['value'].toLowerCase() === "true"; + } + return false; + } catch { + return false; + } +} + +function getModelTokens(model: any): number | undefined { + try { + const tokensProperty = model['properties'].filter( + (property: any) => property[CF_PROPERTY_NAME] === 'max_total_tokens', + ); + if (tokensProperty.length === 1) { + return parseInt(tokensProperty[0]['value']); + } + return undefined; + } catch { + return undefined; + } +} + +class CloudflareStreamTransformer { + private textDecoder = new TextDecoder(); + private buffer: string = ''; + + private parseChunk(chunk: string, controller: TransformStreamDefaultController) { + const dataPrefix = /^data: /; + const json = chunk.replace(dataPrefix, ''); + const parsedChunk = JSON.parse(json); + controller.enqueue(`event: text\n`); + controller.enqueue(`data: ${JSON.stringify(parsedChunk.response)}\n\n`); + } + + public async transform(chunk: Uint8Array, controller: TransformStreamDefaultController) { + let textChunk = this.textDecoder.decode(chunk); + if (this.buffer.trim() !== '') { + textChunk = this.buffer + textChunk; + this.buffer = ''; + } + const splits = textChunk.split('\n\n'); + for (let i = 0; i < splits.length - 1; i++) { + if (/\[DONE]/.test(splits[i].trim())) { + return; + } + this.parseChunk(splits[i], controller); + } + const lastChunk = splits.at(-1)!; + if (lastChunk.trim() !== '') { // else drop. + this.buffer += lastChunk; // does not need to be trimmed. + } + } +} + +export class LobeCloudflareAI implements LobeRuntimeAI { + baseURL: string; + accountID: string; + apiKey?: string; + + constructor({ accountID, apiKey }: LobeCloudflareParams) { + //if (baseURLOrAccountID.startsWith('http')) { + // this.baseURL = baseURLOrAccountID; + // // Try get accountID from baseURL + // this.accountID = baseURLOrAccountID.replaceAll(/^.*\/([\dA-Fa-f]{32})\/.*$/g, '$1'); + //} else { + this.accountID = accountID!; + this.baseURL = fillUrl(accountID!); + //} + this.apiKey = apiKey; + } + + async chat(payload: ChatStreamPayload, options?: ChatCompetitionOptions): Promise { + // Implement your logic here + // This method should handle the chat functionality using the provided payload and options + // It should return a Promise that resolves to a Response object + // You can make API calls, perform computations, or any other necessary operations + + // Example implementation: + try { + const { model, tools, ...restPayload } = payload; + const functions = tools?.map((tool) => tool.function); + const headers = options?.headers || {}; + if (this.apiKey) { + headers['Authorization'] = `Bearer ${this.apiKey}`; + } + const url = new URL(model, this.baseURL); + const response = await fetch(url, { + body: JSON.stringify({ tools: functions, ...restPayload }), + headers: { 'Content-Type': 'application/json', ...headers }, + method: 'POST', + }); + + const desensitizedEndpoint = desensitizeCloudflareUrl(this.baseURL); + + switch (response.status) { + case 400: { + throw AgentRuntimeError.chat({ + endpoint: desensitizedEndpoint, + error: response, + errorType: AgentRuntimeErrorType.ProviderBizError, + provider: ModelProvider.Cloudflare, + }); + } + } + + return StreamingResponse( + response.body!.pipeThrough(new TransformStream(new CloudflareStreamTransformer())) + ); + } catch (error) { + const desensitizedEndpoint = desensitizeCloudflareUrl(this.baseURL); + + throw AgentRuntimeError.chat({ + endpoint: desensitizedEndpoint, + error: error as any, + errorType: AgentRuntimeErrorType.ProviderBizError, + provider: ModelProvider.Cloudflare, + }); + } + } + + async models(): Promise { + try { + const url = `${DEFAULT_BASE_URL_PREFIX}/client/v4/accounts/${this.accountID}/ai/models/search`; + const response = await fetch(url, { + headers: { + 'Authorization': `Bearer ${this.apiKey}`, + 'Content-Type': 'application/json', + }, + method: 'GET', + }); + const j = await response.json(); + const models: any[] = j['result'].filter( + (model: any) => model['task']['name'] === 'Text Generation', + ); + const chatModels: ChatModelCard[] = models.map((model) => { + const modelBeta = getModelBeta(model); + return { + description: model['description'], + displayName: getModelDisplayName(model, modelBeta), + enabled: !modelBeta, + functionCall: getModelFunctionCalling(model), + id: model['name'], + tokens: getModelTokens(model), + }; + }); + return chatModels; + } catch { + return []; + } + } +} diff --git a/src/store/user/slices/modelList/action.ts b/src/store/user/slices/modelList/action.ts index 8e5c5080c464..b3c5516899a6 100644 --- a/src/store/user/slices/modelList/action.ts +++ b/src/store/user/slices/modelList/action.ts @@ -103,6 +103,10 @@ export const createModelListSlice: StateCreator< const togetherai = draft.find((d) => d.id === ModelProvider.TogetherAI); if (togetherai) togetherai.chatModels = mergeModels('togetherai', togetherai.chatModels); + + const cloudflare = draft.find((d) => d.id === ModelProvider.Cloudflare); + if (cloudflare) + cloudflare.chatModels = mergeModels('cloudflare', cloudflare.chatModels); }); set({ defaultModelProviderList }, false, `refreshDefaultModelList - ${params?.trigger}`); From cb7dd1cf09ea872890cf052b7a8f223388a463e9 Mon Sep 17 00:00:00 2001 From: BrandonStudio Date: Wed, 31 Jul 2024 15:19:33 +0800 Subject: [PATCH 29/38] commit check --- src/libs/agent-runtime/AgentRuntime.ts | 8 ++------ src/libs/agent-runtime/cloudflare/index.ts | 17 ++++++++++------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/libs/agent-runtime/AgentRuntime.ts b/src/libs/agent-runtime/AgentRuntime.ts index 5c049a973024..09b4e03c2cae 100644 --- a/src/libs/agent-runtime/AgentRuntime.ts +++ b/src/libs/agent-runtime/AgentRuntime.ts @@ -233,15 +233,11 @@ class AgentRuntime { case ModelProvider.Taichu: { runtimeModel = new LobeTaichuAI(params.taichu ?? {}); - break + break; } case ModelProvider.Cloudflare: { - const cloudflareParams = params.cloudflare ?? {}; - runtimeModel = new LobeCloudflareAI({ - ...cloudflareParams, - baseURL: `https://api.cloudflare.com/client/v4/accounts/${params.cloudflare?.accountID}/ai/v1`, - }); + runtimeModel = new LobeCloudflareAI(params.cloudflare ?? {}); break; } } diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index 8c546988c0a8..eba106fe55aa 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -1,4 +1,5 @@ import { ChatModelCard } from '@/types/llm'; + import { LobeRuntimeAI } from '../BaseAI'; import { AgentRuntimeErrorType } from '../error'; import { ChatCompetitionOptions, ChatStreamPayload, ModelProvider } from '../types'; @@ -40,7 +41,8 @@ function getModelBeta(model: any): boolean { (property: any) => property[CF_PROPERTY_NAME] === 'beta', ); if (betaProperty.length === 1) { - return betaProperty[0]['value'].toLowerCase() === "true"; // This is a string now. + // eslint-disable-next-line eqeqeq + return betaProperty[0]['value'] == true; // This is a string now. } return false; } catch { @@ -63,7 +65,8 @@ function getModelFunctionCalling(model: any): boolean { (property: any) => property[CF_PROPERTY_NAME] === 'function_calling', ); if (fcProperty.length === 1) { - return fcProperty[0]['value'].toLowerCase() === "true"; + // eslint-disable-next-line eqeqeq + return fcProperty[0]['value'] == true; } return false; } catch { @@ -111,9 +114,9 @@ class CloudflareStreamTransformer { this.parseChunk(splits[i], controller); } const lastChunk = splits.at(-1)!; - if (lastChunk.trim() !== '') { // else drop. + if (lastChunk.trim() !== '') { this.buffer += lastChunk; // does not need to be trimmed. - } + } // else drop. } } @@ -128,8 +131,8 @@ export class LobeCloudflareAI implements LobeRuntimeAI { // // Try get accountID from baseURL // this.accountID = baseURLOrAccountID.replaceAll(/^.*\/([\dA-Fa-f]{32})\/.*$/g, '$1'); //} else { - this.accountID = accountID!; - this.baseURL = fillUrl(accountID!); + this.accountID = accountID!; + this.baseURL = fillUrl(accountID!); //} this.apiKey = apiKey; } @@ -169,7 +172,7 @@ export class LobeCloudflareAI implements LobeRuntimeAI { } return StreamingResponse( - response.body!.pipeThrough(new TransformStream(new CloudflareStreamTransformer())) + response.body!.pipeThrough(new TransformStream(new CloudflareStreamTransformer())), ); } catch (error) { const desensitizedEndpoint = desensitizeCloudflareUrl(this.baseURL); From ac8d4f287c8fd3e784692e38460cf35dc5a96811 Mon Sep 17 00:00:00 2001 From: BrandonStudio Date: Wed, 31 Jul 2024 15:21:52 +0800 Subject: [PATCH 30/38] disable function calling for now --- src/libs/agent-runtime/cloudflare/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index eba106fe55aa..dadee1c0040a 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -60,6 +60,8 @@ function getModelDisplayName(model: any, beta: boolean): string { } function getModelFunctionCalling(model: any): boolean { + return false; + // eslint-disable-next-line no-unreachable try { const fcProperty = model['properties'].filter( (property: any) => property[CF_PROPERTY_NAME] === 'function_calling', From eefacf564ac10934bbe266f1608a519f64088393 Mon Sep 17 00:00:00 2001 From: BrandonStudio Date: Wed, 31 Jul 2024 16:12:37 +0800 Subject: [PATCH 31/38] does not catch errors when fetching models --- src/libs/agent-runtime/cloudflare/index.ts | 52 ++++++++++------------ 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index dadee1c0040a..da476724e5f1 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -189,33 +189,29 @@ export class LobeCloudflareAI implements LobeRuntimeAI { } async models(): Promise { - try { - const url = `${DEFAULT_BASE_URL_PREFIX}/client/v4/accounts/${this.accountID}/ai/models/search`; - const response = await fetch(url, { - headers: { - 'Authorization': `Bearer ${this.apiKey}`, - 'Content-Type': 'application/json', - }, - method: 'GET', - }); - const j = await response.json(); - const models: any[] = j['result'].filter( - (model: any) => model['task']['name'] === 'Text Generation', - ); - const chatModels: ChatModelCard[] = models.map((model) => { - const modelBeta = getModelBeta(model); - return { - description: model['description'], - displayName: getModelDisplayName(model, modelBeta), - enabled: !modelBeta, - functionCall: getModelFunctionCalling(model), - id: model['name'], - tokens: getModelTokens(model), - }; - }); - return chatModels; - } catch { - return []; - } + const url = `${DEFAULT_BASE_URL_PREFIX}/client/v4/accounts/${this.accountID}/ai/models/search`; + const response = await fetch(url, { + headers: { + 'Authorization': `Bearer ${this.apiKey}`, + 'Content-Type': 'application/json', + }, + method: 'GET', + }); + const j = await response.json(); + const models: any[] = j['result'].filter( + (model: any) => model['task']['name'] === 'Text Generation', + ); + const chatModels: ChatModelCard[] = models.map((model) => { + const modelBeta = getModelBeta(model); + return { + description: model['description'], + displayName: getModelDisplayName(model, modelBeta), + enabled: !modelBeta, + functionCall: getModelFunctionCalling(model), + id: model['name'], + tokens: getModelTokens(model), + }; + }); + return chatModels; } } From 5fc4c81155efc69e5990feca2c5ff1f829829408 Mon Sep 17 00:00:00 2001 From: BrandonStudio Date: Wed, 31 Jul 2024 16:50:49 +0800 Subject: [PATCH 32/38] ready to add base url --- .../llm/ProviderList/Cloudflare/index.tsx | 11 ++++----- src/app/api/chat/agentRuntime.ts | 8 +++---- src/const/auth.ts | 2 +- src/libs/agent-runtime/cloudflare/index.ts | 23 +++++++++++-------- src/locales/default/modelProvider.ts | 10 ++++---- src/services/_auth.ts | 6 ++--- src/services/chat.ts | 2 +- src/types/user/settings/keyVaults.ts | 2 +- 8 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/app/(main)/settings/llm/ProviderList/Cloudflare/index.tsx b/src/app/(main)/settings/llm/ProviderList/Cloudflare/index.tsx index 792733c016c9..f493a46068b8 100644 --- a/src/app/(main)/settings/llm/ProviderList/Cloudflare/index.tsx +++ b/src/app/(main)/settings/llm/ProviderList/Cloudflare/index.tsx @@ -31,14 +31,13 @@ export const useCloudflareProvider = (): ProviderItem => { }, { children: ( - ), - desc: t(`${providerKey}.accountID.desc`), - label: t(`${providerKey}.accountID.title`), - name: [KeyVaultsConfigKey, providerKey, 'accountID'], + desc: t(`${providerKey}.baseURLOrAccountID.desc`), + label: t(`${providerKey}.baseURLOrAccountID.title`), + name: [KeyVaultsConfigKey, providerKey, 'baseURLOrAccountID'], }, ], title: , diff --git a/src/app/api/chat/agentRuntime.ts b/src/app/api/chat/agentRuntime.ts index d9a6d1a12628..f4602b10e8bf 100644 --- a/src/app/api/chat/agentRuntime.ts +++ b/src/app/api/chat/agentRuntime.ts @@ -190,12 +190,12 @@ const getLlmOptionsFromPayload = (provider: string, payload: JWTPayload) => { const { CLOUDFLARE_API_KEY, CLOUDFLARE_ACCOUNT_ID } = getLLMConfig(); const apiKey = apiKeyManager.pick(payload?.apiKey || CLOUDFLARE_API_KEY); - const accountID = - payload.apiKey && payload.cloudflareAccountID - ? payload.cloudflareAccountID + const baseURLOrAccountID = + payload.apiKey && payload.cloudflareBaseURLOrAccountID + ? payload.cloudflareBaseURLOrAccountID : CLOUDFLARE_ACCOUNT_ID; - return { accountID, apiKey }; + return { apiKey, baseURLOrAccountID }; } } }; diff --git a/src/const/auth.ts b/src/const/auth.ts index 7b52a8374ea0..d59b44d435e4 100644 --- a/src/const/auth.ts +++ b/src/const/auth.ts @@ -36,7 +36,7 @@ export interface JWTPayload { awsRegion?: string; awsSecretAccessKey?: string; - cloudflareAccountID?: string; + cloudflareBaseURLOrAccountID?: string; /** * user id * in client db mode it's a uuid diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index da476724e5f1..630e637e0a87 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -10,8 +10,8 @@ import { StreamingResponse } from '../utils/response'; const DEFAULT_BASE_URL_PREFIX = 'https://api.cloudflare.com'; export interface LobeCloudflareParams { - accountID?: string; apiKey?: string; + baseURLOrAccountID?: string, } function fillUrl(accountID: string): string { @@ -127,15 +127,18 @@ export class LobeCloudflareAI implements LobeRuntimeAI { accountID: string; apiKey?: string; - constructor({ accountID, apiKey }: LobeCloudflareParams) { - //if (baseURLOrAccountID.startsWith('http')) { - // this.baseURL = baseURLOrAccountID; - // // Try get accountID from baseURL - // this.accountID = baseURLOrAccountID.replaceAll(/^.*\/([\dA-Fa-f]{32})\/.*$/g, '$1'); - //} else { - this.accountID = accountID!; - this.baseURL = fillUrl(accountID!); - //} + constructor({ apiKey, baseURLOrAccountID }: LobeCloudflareParams) { + if (!baseURLOrAccountID) { + throw AgentRuntimeError.createError(AgentRuntimeErrorType.InvalidProviderAPIKey); + } + if (baseURLOrAccountID.startsWith('http')) { + this.baseURL = baseURLOrAccountID.endsWith('/') ? baseURLOrAccountID : baseURLOrAccountID + '/'; + // Try get accountID from baseURL + this.accountID = baseURLOrAccountID.replaceAll(/^.*\/([\dA-Fa-f]{32})\/.*$/g, '$1'); + } else { + this.accountID = baseURLOrAccountID; + this.baseURL = fillUrl(baseURLOrAccountID); + } this.apiKey = apiKey; } diff --git a/src/locales/default/modelProvider.ts b/src/locales/default/modelProvider.ts index 37abf3721dec..212892af66d0 100644 --- a/src/locales/default/modelProvider.ts +++ b/src/locales/default/modelProvider.ts @@ -47,16 +47,16 @@ export default { }, }, cloudflare: { - accountID: { - desc: '请填写 Cloudflare 账户 ID', - placeholder: 'Cloudflare Account ID', - title: 'Cloudflare Account ID', - }, apiKey: { desc: '请填写 Cloudflare API Key', placeholder: 'Cloudflare API Key', title: 'Cloudflare API Key', }, + baseURLOrAccountID: { + desc: '填入 Cloudflare 账户 ID 或 自定义 API 地址', + placeholder: 'Cloudflare Account ID / custom API URL', + title: 'Cloudflare 账户 ID / API 地址', + }, }, ollama: { checker: { diff --git a/src/services/_auth.ts b/src/services/_auth.ts index 127920b8f487..db500c152e6f 100644 --- a/src/services/_auth.ts +++ b/src/services/_auth.ts @@ -39,9 +39,9 @@ export const getProviderAuthPayload = (provider: string) => { case ModelProvider.Cloudflare: { const config = keyVaultsConfigSelectors.cloudflareConfig(useUserStore.getState()); - return { - apiKey: config?.apiKey, - cloudflareAccountID: config?.accountID, + return { + apiKey: config?.apiKey, + cloudflareBaseURLOrAccountID: config?.baseURLOrAccountID, }; } diff --git a/src/services/chat.ts b/src/services/chat.ts index 435f50662400..962ed2962f51 100644 --- a/src/services/chat.ts +++ b/src/services/chat.ts @@ -160,8 +160,8 @@ export function initializeWithClientStore(provider: string, payload: any) { } case ModelProvider.Cloudflare: { providerOptions = { - accountID: providerAuthPayload?.cloudflareAccountID, apikey: providerAuthPayload?.apiKey, + baseURLOrAccountID: providerAuthPayload?.cloudflareBaseURLOrAccountID, }; break; } diff --git a/src/types/user/settings/keyVaults.ts b/src/types/user/settings/keyVaults.ts index 72445ea0ea4d..81314d951242 100644 --- a/src/types/user/settings/keyVaults.ts +++ b/src/types/user/settings/keyVaults.ts @@ -16,8 +16,8 @@ export interface AWSBedrockKeyVault { } export interface CloudflareKeyVault { - accountID?: string; apiKey?: string; + baseURLOrAccountID?: string; } export interface UserKeyVaults { From 52ff9d13f1e156bf0bd0b685ea38406c80b2a85d Mon Sep 17 00:00:00 2001 From: BrandonStudio Date: Wed, 31 Jul 2024 16:51:20 +0800 Subject: [PATCH 33/38] commit check --- src/libs/agent-runtime/cloudflare/index.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index 630e637e0a87..25474f18279c 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -11,7 +11,7 @@ const DEFAULT_BASE_URL_PREFIX = 'https://api.cloudflare.com'; export interface LobeCloudflareParams { apiKey?: string; - baseURLOrAccountID?: string, + baseURLOrAccountID?: string; } function fillUrl(accountID: string): string { @@ -132,7 +132,9 @@ export class LobeCloudflareAI implements LobeRuntimeAI { throw AgentRuntimeError.createError(AgentRuntimeErrorType.InvalidProviderAPIKey); } if (baseURLOrAccountID.startsWith('http')) { - this.baseURL = baseURLOrAccountID.endsWith('/') ? baseURLOrAccountID : baseURLOrAccountID + '/'; + this.baseURL = baseURLOrAccountID.endsWith('/') + ? baseURLOrAccountID + : baseURLOrAccountID + '/'; // Try get accountID from baseURL this.accountID = baseURLOrAccountID.replaceAll(/^.*\/([\dA-Fa-f]{32})\/.*$/g, '$1'); } else { From b8492e2d4030f09111c031a82fa6b6b742934e35 Mon Sep 17 00:00:00 2001 From: BrandonStudio Date: Thu, 1 Aug 2024 09:38:03 +0800 Subject: [PATCH 34/38] revert change --- src/libs/agent-runtime/AgentRuntime.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/agent-runtime/AgentRuntime.ts b/src/libs/agent-runtime/AgentRuntime.ts index 09b4e03c2cae..2f886d783fa3 100644 --- a/src/libs/agent-runtime/AgentRuntime.ts +++ b/src/libs/agent-runtime/AgentRuntime.ts @@ -233,7 +233,7 @@ class AgentRuntime { case ModelProvider.Taichu: { runtimeModel = new LobeTaichuAI(params.taichu ?? {}); - break; + break } case ModelProvider.Cloudflare: { From b452d30f0fc2f02a10b71b423eaa9e32146e2647 Mon Sep 17 00:00:00 2001 From: BrandonStudio Date: Thu, 1 Aug 2024 12:35:21 +0800 Subject: [PATCH 35/38] revert string boolean check --- src/libs/agent-runtime/cloudflare/index.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index 25474f18279c..4edf34ac519c 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -41,8 +41,7 @@ function getModelBeta(model: any): boolean { (property: any) => property[CF_PROPERTY_NAME] === 'beta', ); if (betaProperty.length === 1) { - // eslint-disable-next-line eqeqeq - return betaProperty[0]['value'] == true; // This is a string now. + return betaProperty[0]['value'] === 'true'; // This is a string now. } return false; } catch { @@ -67,8 +66,7 @@ function getModelFunctionCalling(model: any): boolean { (property: any) => property[CF_PROPERTY_NAME] === 'function_calling', ); if (fcProperty.length === 1) { - // eslint-disable-next-line eqeqeq - return fcProperty[0]['value'] == true; + return fcProperty[0]['value'] === 'true'; } return false; } catch { From b46c642dbf30fdc6be3b00a51c10b7bdf7e98bfa Mon Sep 17 00:00:00 2001 From: BrandonStudio Date: Thu, 1 Aug 2024 13:35:57 +0800 Subject: [PATCH 36/38] fix type error on Vercel. refer to https://github.com/vercel/next.js/issues/38736#issuecomment-1278917422 --- src/libs/agent-runtime/cloudflare/index.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index 4edf34ac519c..6dcf9de3e4b4 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -90,14 +90,15 @@ function getModelTokens(model: any): number | undefined { class CloudflareStreamTransformer { private textDecoder = new TextDecoder(); + private textEncoder = new TextEncoder(); private buffer: string = ''; private parseChunk(chunk: string, controller: TransformStreamDefaultController) { const dataPrefix = /^data: /; const json = chunk.replace(dataPrefix, ''); const parsedChunk = JSON.parse(json); - controller.enqueue(`event: text\n`); - controller.enqueue(`data: ${JSON.stringify(parsedChunk.response)}\n\n`); + controller.enqueue(this.textEncoder.encode(`event: text\n`)); + controller.enqueue(this.textEncoder.encode(`data: ${JSON.stringify(parsedChunk.response)}\n\n`)); } public async transform(chunk: Uint8Array, controller: TransformStreamDefaultController) { From 2dca07de07505dd1f5528bec20ba270c374ab7eb Mon Sep 17 00:00:00 2001 From: BrandonStudio Date: Thu, 1 Aug 2024 15:30:12 +0800 Subject: [PATCH 37/38] i18n by groq/llama-3.1-8b-instant --- locales/ar/modelProvider.json | 10 +++++----- locales/bg-BG/modelProvider.json | 10 +++++----- locales/de-DE/modelProvider.json | 10 +++++----- locales/en-US/modelProvider.json | 10 +++++----- locales/es-ES/modelProvider.json | 10 +++++----- locales/fr-FR/modelProvider.json | 10 +++++----- locales/it-IT/modelProvider.json | 10 +++++----- locales/ja-JP/modelProvider.json | 10 +++++----- locales/ko-KR/modelProvider.json | 10 +++++----- locales/nl-NL/modelProvider.json | 10 +++++----- locales/pl-PL/modelProvider.json | 10 +++++----- locales/pt-BR/modelProvider.json | 10 +++++----- locales/ru-RU/modelProvider.json | 10 +++++----- locales/tr-TR/modelProvider.json | 10 +++++----- locales/vi-VN/modelProvider.json | 10 +++++----- locales/zh-CN/modelProvider.json | 10 +++++----- locales/zh-TW/modelProvider.json | 10 +++++----- 17 files changed, 85 insertions(+), 85 deletions(-) diff --git a/locales/ar/modelProvider.json b/locales/ar/modelProvider.json index 4247dc8af16a..4309bfc7bb13 100644 --- a/locales/ar/modelProvider.json +++ b/locales/ar/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "يرجى ملء Cloudflare Account ID", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "يرجى ملء Cloudflare API Key", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "أدخل رقم حساب Cloudflare أو عنوان URL API المخصص", + "placeholder": "رقم حساب Cloudflare / عنوان URL API المخصص", + "title": "رقم حساب Cloudflare / عنوان URL API" } }, "ollama": { diff --git a/locales/bg-BG/modelProvider.json b/locales/bg-BG/modelProvider.json index 66ad791e5e6f..58cbdf423724 100644 --- a/locales/bg-BG/modelProvider.json +++ b/locales/bg-BG/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "Моля, въведете Cloudflare Account ID", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "Моля, въведете Cloudflare API Key", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "Въведете ID на Cloudflare или личен API адрес", + "placeholder": "ID на Cloudflare / личен API адрес", + "title": "ID на Cloudflare / API адрес" } }, "ollama": { diff --git a/locales/de-DE/modelProvider.json b/locales/de-DE/modelProvider.json index e48adf2d5502..5db4af046e8f 100644 --- a/locales/de-DE/modelProvider.json +++ b/locales/de-DE/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "Bitte füllen Sie die Cloudflare Account ID", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "Bitte füllen Sie die Cloudflare API Key", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "Eingeben Sie die Cloudflare-Kundenkennung oder die benutzerdefinierte API-Adresse", + "placeholder": "Cloudflare-Kundenkennung / benutzerdefinierte API-Adresse", + "title": "Cloudflare-Kundenkennung / API-Adresse" } }, "ollama": { diff --git a/locales/en-US/modelProvider.json b/locales/en-US/modelProvider.json index 970d359e3bbf..790774a75989 100644 --- a/locales/en-US/modelProvider.json +++ b/locales/en-US/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "Please enter Cloudflare Account ID", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "Please enter Cloudflare API Key", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "Enter your Cloudflare account ID or custom API address", + "placeholder": "Cloudflare Account ID / custom API URL", + "title": "Cloudflare Account ID / API Address" } }, "ollama": { diff --git a/locales/es-ES/modelProvider.json b/locales/es-ES/modelProvider.json index eb23eb33e4a6..5e1a91d336cb 100644 --- a/locales/es-ES/modelProvider.json +++ b/locales/es-ES/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "Por favor complete la Cloudflare Account ID", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "Por favor complete la Cloudflare API Key", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "Ingrese el ID de cuenta de Cloudflare o la dirección URL personalizada de API", + "placeholder": "ID de cuenta de Cloudflare / URL de API personalizada", + "title": "ID de cuenta de Cloudflare / dirección URL de API" } }, "ollama": { diff --git a/locales/fr-FR/modelProvider.json b/locales/fr-FR/modelProvider.json index 0854054c97e3..88244b17c664 100644 --- a/locales/fr-FR/modelProvider.json +++ b/locales/fr-FR/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "Veuillez remplir l'Cloudflare Account ID", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "Veuillez remplir l'Cloudflare API Key", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "Saisir l'ID de compte Cloudflare ou l'adresse API personnalisée", + "placeholder": "ID de compte Cloudflare / URL API personnalisée", + "title": "ID de compte Cloudflare / adresse API" } }, "ollama": { diff --git a/locales/it-IT/modelProvider.json b/locales/it-IT/modelProvider.json index 04c5d7e1c99f..3d1bd5ca45ed 100644 --- a/locales/it-IT/modelProvider.json +++ b/locales/it-IT/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "Compila l'Cloudflare Account ID", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "Compila l'Cloudflare API Key", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "Inserisci l'ID dell'account Cloudflare o l'indirizzo API personalizzato", + "placeholder": "ID account Cloudflare / URL API personalizzato", + "title": "ID account Cloudflare / indirizzo API" } }, "ollama": { diff --git a/locales/ja-JP/modelProvider.json b/locales/ja-JP/modelProvider.json index f8e564f0cf92..2c9250b20faf 100644 --- a/locales/ja-JP/modelProvider.json +++ b/locales/ja-JP/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "Cloudflare Account ID を入力してください", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "Cloudflare API Key を入力してください", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "Cloudflare アカウント ID またはカスタム API アドレスを入力してください。", + "placeholder": "Cloudflare アカウント ID / カスタム API URL", + "title": "Cloudflare アカウント ID / API アドレス" } }, "ollama": { diff --git a/locales/ko-KR/modelProvider.json b/locales/ko-KR/modelProvider.json index 55ef3c42957f..0bafa0152c45 100644 --- a/locales/ko-KR/modelProvider.json +++ b/locales/ko-KR/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "Cloudflare Account ID 를 작성해 주세요.", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "Cloudflare API Key 를 작성해 주세요.", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "클라우드 플레어 계정 ID 또는 사용자 지정 API 주소 입력", + "placeholder": "클라우드 플레어 계정 ID / 사용자 지정 API 주소", + "title": "클라우드 플레어 계정 ID / API 주소" } }, "ollama": { diff --git a/locales/nl-NL/modelProvider.json b/locales/nl-NL/modelProvider.json index 6d4d00003015..d78ed31d6c93 100644 --- a/locales/nl-NL/modelProvider.json +++ b/locales/nl-NL/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "Voer Cloudflare Account ID in", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "Voer Cloudflare API Key in", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "Voer uw Cloudflare-account ID of een custom API-URL in", + "placeholder": "Cloudflare-account ID / custom API-URL", + "title": "Cloudflare-account ID / API-URL" } }, "ollama": { diff --git a/locales/pl-PL/modelProvider.json b/locales/pl-PL/modelProvider.json index 2e495cd7e0f2..d5174c91069c 100644 --- a/locales/pl-PL/modelProvider.json +++ b/locales/pl-PL/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "Wprowadź klucz Cloudflare Account ID", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "Wprowadź klucz Cloudflare API Key", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "Wprowadź ID konta Cloudflare lub adres API niestandardowy", + "placeholder": "ID konta Cloudflare / adres API niestandardowy", + "title": "ID konta Cloudflare / adres API" } }, "ollama": { diff --git a/locales/pt-BR/modelProvider.json b/locales/pt-BR/modelProvider.json index cd2a437de5b8..8846ac4bbe26 100644 --- a/locales/pt-BR/modelProvider.json +++ b/locales/pt-BR/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "Insira o Cloudflare Account ID", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "Insira o Cloudflare API Key", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "Insira o ID da conta do Cloudflare ou o endereço da API personalizado", + "placeholder": "ID da conta do Cloudflare / URL da API personalizada", + "title": "ID da conta do Cloudflare / Endereço da API" } }, "ollama": { diff --git a/locales/ru-RU/modelProvider.json b/locales/ru-RU/modelProvider.json index 5c07b72dcdd3..93750ccea50c 100644 --- a/locales/ru-RU/modelProvider.json +++ b/locales/ru-RU/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "Пожалуйста, заполните Cloudflare Account ID", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "Пожалуйста, заполните Cloudflare API Key", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "Введите ID аккаунта Cloudflare или адрес API по умолчанию", + "placeholder": "ID аккаунта Cloudflare / адрес API по умолчанию", + "title": "ID аккаунта Cloudflare / адрес API" } }, "ollama": { diff --git a/locales/tr-TR/modelProvider.json b/locales/tr-TR/modelProvider.json index c059b28b2587..a4db2aad44a6 100644 --- a/locales/tr-TR/modelProvider.json +++ b/locales/tr-TR/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "Lütfen doldurun Cloudflare Account ID", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "Lütfen doldurun Cloudflare API Key", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "Cloudflare hesabınızın ID'sini veya özel API adresinizi girin", + "placeholder": "Cloudflare Hesap ID / Özel API Adresi", + "title": "Cloudflare Hesap ID / API Adresi" } }, "ollama": { diff --git a/locales/vi-VN/modelProvider.json b/locales/vi-VN/modelProvider.json index 9da7c7ac3204..46a027430b40 100644 --- a/locales/vi-VN/modelProvider.json +++ b/locales/vi-VN/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "Vui lòng nhập Cloudflare Account ID", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "Vui lòng nhập Cloudflare API Key", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "Nhập ID tài khoản Cloudflare hoặc địa chỉ API tùy chỉnh", + "placeholder": "ID tài khoản Cloudflare / địa chỉ API tùy chỉnh", + "title": "ID tài khoản Cloudflare / địa chỉ API" } }, "ollama": { diff --git a/locales/zh-CN/modelProvider.json b/locales/zh-CN/modelProvider.json index e99a88b11ccf..701fe0aab6cf 100644 --- a/locales/zh-CN/modelProvider.json +++ b/locales/zh-CN/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "请填写 Cloudflare 账户 ID", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "请填写 Cloudflare API Key", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "填入 Cloudflare 账户 ID 或 自定义 API 地址", + "placeholder": "Cloudflare Account ID / custom API URL", + "title": "Cloudflare 账户 ID / API 地址" } }, "ollama": { diff --git a/locales/zh-TW/modelProvider.json b/locales/zh-TW/modelProvider.json index a9a33461ad61..e1c2e120dfca 100644 --- a/locales/zh-TW/modelProvider.json +++ b/locales/zh-TW/modelProvider.json @@ -46,15 +46,15 @@ } }, "cloudflare": { - "accountID": { - "desc": "請填入 Cloudflare 帳戶 ID", - "placeholder": "Cloudflare Account ID", - "title": "Cloudflare Account ID" - }, "apiKey": { "desc": "請填入 Cloudflare API Key", "placeholder": "Cloudflare API Key", "title": "Cloudflare API Key" + }, + "baseURLOrAccountID": { + "desc": "填入 Cloudflare 帳戶 ID 或 自定義 API 位址", + "placeholder": "Cloudflare 帳戶 ID / 自定義 API 位址", + "title": "Cloudflare 帳戶 ID / API 位址" } }, "ollama": { From 0f40d15cdb3b9c8700e80034d5cd53344b494c64 Mon Sep 17 00:00:00 2001 From: BrandonStudio Date: Thu, 1 Aug 2024 17:18:25 +0800 Subject: [PATCH 38/38] rename env var --- .env.example | 2 +- src/app/api/chat/agentRuntime.ts | 4 ++-- src/config/llm.ts | 7 ++++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.env.example b/.env.example index 5c25dc153d9a..e7968faf79ce 100644 --- a/.env.example +++ b/.env.example @@ -114,8 +114,8 @@ OPENAI_API_KEY=sk-xxxxxxxxx ### Cloudflare Workers AI #### -# CLOUDFLARE_ACCOUNT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # CLOUDFLARE_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx +# CLOUDFLARE_BASE_URL_OR_ACCOUNT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ######################################## diff --git a/src/app/api/chat/agentRuntime.ts b/src/app/api/chat/agentRuntime.ts index f4602b10e8bf..c6a9f8925f1f 100644 --- a/src/app/api/chat/agentRuntime.ts +++ b/src/app/api/chat/agentRuntime.ts @@ -187,13 +187,13 @@ const getLlmOptionsFromPayload = (provider: string, payload: JWTPayload) => { return { apiKey }; } case ModelProvider.Cloudflare: { - const { CLOUDFLARE_API_KEY, CLOUDFLARE_ACCOUNT_ID } = getLLMConfig(); + const { CLOUDFLARE_API_KEY, CLOUDFLARE_BASE_URL_OR_ACCOUNT_ID } = getLLMConfig(); const apiKey = apiKeyManager.pick(payload?.apiKey || CLOUDFLARE_API_KEY); const baseURLOrAccountID = payload.apiKey && payload.cloudflareBaseURLOrAccountID ? payload.cloudflareBaseURLOrAccountID - : CLOUDFLARE_ACCOUNT_ID; + : CLOUDFLARE_BASE_URL_OR_ACCOUNT_ID; return { apiKey, baseURLOrAccountID }; } diff --git a/src/config/llm.ts b/src/config/llm.ts index b025a6dacca0..a22dead7318d 100644 --- a/src/config/llm.ts +++ b/src/config/llm.ts @@ -91,7 +91,7 @@ export const getLLMConfig = () => { ENABLED_CLOUDFLARE: z.boolean(), CLOUDFLARE_API_KEY: z.string().optional(), - CLOUDFLARE_ACCOUNT_ID: z.string().optional(), + CLOUDFLARE_BASE_URL_OR_ACCOUNT_ID: z.string().optional(), }, runtimeEnv: { API_KEY_SELECT_MODE: process.env.API_KEY_SELECT_MODE, @@ -172,9 +172,10 @@ export const getLLMConfig = () => { ENABLED_TAICHU: !!process.env.TAICHU_API_KEY, TAICHU_API_KEY: process.env.TAICHU_API_KEY, - ENABLED_CLOUDFLARE: !!process.env.CLOUDFLARE_API_KEY && !!process.env.CLOUDFLARE_ACCOUNT_ID, + ENABLED_CLOUDFLARE: + !!process.env.CLOUDFLARE_API_KEY && !!process.env.CLOUDFLARE_BASE_URL_OR_ACCOUNT_ID, CLOUDFLARE_API_KEY: process.env.CLOUDFLARE_API_KEY, - CLOUDFLARE_ACCOUNT_ID: process.env.CLOUDFLARE_ACCOUNT_ID, + CLOUDFLARE_BASE_URL_OR_ACCOUNT_ID: process.env.CLOUDFLARE_BASE_URL_OR_ACCOUNT_ID, }, }); };