From 14091f2b2b5410322a3009838b038ffe06a89d46 Mon Sep 17 00:00:00 2001 From: saikidev Date: Mon, 17 Feb 2025 16:43:08 +0800 Subject: [PATCH] add deepseek model --- README.md | 1 + src/app/bots/deepseek-api/index.ts | 36 ++++++++++++++ src/app/bots/deepseek-ppio/index.ts | 36 ++++++++++++++ src/app/bots/deepseek/index.ts | 21 ++++++++ src/app/bots/index.ts | 4 ++ .../Settings/DeepSeekAPISettings.tsx | 48 +++++++++++++++++++ .../Settings/DeepSeekPPIOSettings.tsx | 48 +++++++++++++++++++ src/app/consts.ts | 5 ++ src/app/pages/SettingPage.tsx | 15 ++++++ src/assets/logos/deepseek.svg | 6 +++ src/services/user-config.ts | 19 ++++++++ 11 files changed, 239 insertions(+) create mode 100644 src/app/bots/deepseek-api/index.ts create mode 100644 src/app/bots/deepseek-ppio/index.ts create mode 100644 src/app/bots/deepseek/index.ts create mode 100644 src/app/components/Settings/DeepSeekAPISettings.tsx create mode 100644 src/app/components/Settings/DeepSeekPPIOSettings.tsx create mode 100644 src/assets/logos/deepseek.svg diff --git a/README.md b/README.md index 5f093047e..35613f8a1 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ - iFlytek Spark - Tongyi Qianwen - Baichuan +- Deepseek (via API/PPIO) - ... ## 🔨 Build from Source diff --git a/src/app/bots/deepseek-api/index.ts b/src/app/bots/deepseek-api/index.ts new file mode 100644 index 000000000..32fa80735 --- /dev/null +++ b/src/app/bots/deepseek-api/index.ts @@ -0,0 +1,36 @@ +import { UserConfig } from '~services/user-config' +import { AbstractChatGPTApiBot } from '../chatgpt-api' +import { ChatMessage } from '../chatgpt-api/types' + +export class DeepSeekApiBot extends AbstractChatGPTApiBot { + constructor( + private config: Pick< + UserConfig, + 'deepseekApiKey' | + 'deepseekApiModel' + >, + ) { + super() + } + + async fetchCompletionApi(messages: ChatMessage[], signal?: AbortSignal) { + const endpoint = `https://api.deepseek.com/chat/completions` + return fetch(endpoint, { + method: 'POST', + signal, + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${this.config.deepseekApiKey}`, + }, + body: JSON.stringify({ + messages, + stream: true, + model: this.config.deepseekApiModel + }), + }) + } + + get name() { + return `DeepSeek API` + } +} diff --git a/src/app/bots/deepseek-ppio/index.ts b/src/app/bots/deepseek-ppio/index.ts new file mode 100644 index 000000000..63deca0b5 --- /dev/null +++ b/src/app/bots/deepseek-ppio/index.ts @@ -0,0 +1,36 @@ +import { UserConfig } from '~services/user-config' +import { AbstractChatGPTApiBot } from '../chatgpt-api' +import { ChatMessage } from '../chatgpt-api/types' + +export class DeepSeekPpioBot extends AbstractChatGPTApiBot { + constructor( + private config: Pick< + UserConfig, + 'deepseekPpioKey' | + 'deepseekPpioModel' + >, + ) { + super() + } + + async fetchCompletionApi(messages: ChatMessage[], signal?: AbortSignal) { + const endpoint = `https://api.ppinfra.com/v3/openai/chat/completions` + return fetch(endpoint, { + method: 'POST', + signal, + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${this.config.deepseekPpioKey}`, + }, + body: JSON.stringify({ + messages, + stream: true, + model: this.config.deepseekPpioModel + }), + }) + } + + get name() { + return `DeepSeek PPIO API` + } +} diff --git a/src/app/bots/deepseek/index.ts b/src/app/bots/deepseek/index.ts new file mode 100644 index 000000000..53d8d3ed6 --- /dev/null +++ b/src/app/bots/deepseek/index.ts @@ -0,0 +1,21 @@ +import { DeepSeekMode, getUserConfig } from '~/services/user-config' +import { AsyncAbstractBot } from '../abstract-bot' +import { DeepSeekApiBot } from '../deepseek-api' +import { DeepSeekPpioBot } from '../deepseek-ppio' + +export class DeepSeekBot extends AsyncAbstractBot { + async initializeBot() { + const { deepseekMode, ...config } = await getUserConfig() + if (deepseekMode === DeepSeekMode.API) { + if (!config.deepseekApiKey) { + throw new Error('DeepSeek API key missing') + } + return new DeepSeekApiBot(config) + } else { + if (!config.deepseekPpioKey) { + throw new Error('DeepSeek PPIO API key missing') + } + return new DeepSeekPpioBot(config) + } + } +} diff --git a/src/app/bots/index.ts b/src/app/bots/index.ts index f9983fb3a..8eed12839 100644 --- a/src/app/bots/index.ts +++ b/src/app/bots/index.ts @@ -3,6 +3,7 @@ import { BardBot } from './bard' import { BingWebBot } from './bing' import { ChatGPTBot } from './chatgpt' import { ClaudeBot } from './claude' +import { DeepSeekBot } from './deepseek' import { GeminiBot } from './gemini-api' import { GrokWebBot } from './grok' import { LMSYSBot } from './lmsys' @@ -30,6 +31,7 @@ export type BotId = | 'yi' | 'grok' | 'gemini' + | 'deepseek' export function createBotInstance(botId: BotId) { switch (botId) { @@ -69,6 +71,8 @@ export function createBotInstance(botId: BotId) { return new GrokWebBot() case 'gemini': return new GeminiBot() + case 'deepseek': + return new DeepSeekBot() } } diff --git a/src/app/components/Settings/DeepSeekAPISettings.tsx b/src/app/components/Settings/DeepSeekAPISettings.tsx new file mode 100644 index 000000000..264b69819 --- /dev/null +++ b/src/app/components/Settings/DeepSeekAPISettings.tsx @@ -0,0 +1,48 @@ +import { FC } from 'react' +import { useTranslation } from 'react-i18next' +import { DeepSeekAPIModel, UserConfig } from '~services/user-config' +import { Input } from '../Input' +import Select from '../Select' +import Blockquote from './Blockquote' + +interface Props { + userConfig: UserConfig + updateConfigValue: (update: Partial) => void +} + +const DeepSeekAPISettings: FC = ({ userConfig, updateConfigValue }) => { + const { t } = useTranslation() + return ( +
+
+

API Key ( + + how to create key + + )

+ updateConfigValue({ deepseekApiKey: e.currentTarget.value })} + type="password" + /> +
{t('Your keys are stored locally')}
+
+
+

{t('Model')}

+ updateConfigValue({ deepseekPpioKey: e.currentTarget.value })} + type="password" + /> +
{t('Your keys are stored locally')}
+
+
+

{t('Model')}

+