@lobehub/chat 1.48.3 → 1.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/changelog/v1.json +18 -0
- package/docker-compose/local/setup.sh +16 -6
- package/docs/self-hosting/server-database/docker-compose.zh-CN.mdx +197 -194
- package/locales/ar/chat.json +0 -4
- package/locales/ar/components.json +5 -0
- package/locales/bg-BG/chat.json +0 -4
- package/locales/bg-BG/components.json +5 -0
- package/locales/de-DE/chat.json +0 -4
- package/locales/de-DE/components.json +5 -0
- package/locales/en-US/chat.json +0 -4
- package/locales/en-US/components.json +5 -0
- package/locales/es-ES/chat.json +0 -4
- package/locales/es-ES/components.json +5 -0
- package/locales/fa-IR/chat.json +0 -4
- package/locales/fa-IR/components.json +5 -0
- package/locales/fr-FR/chat.json +0 -4
- package/locales/fr-FR/components.json +5 -0
- package/locales/it-IT/chat.json +0 -4
- package/locales/it-IT/components.json +5 -0
- package/locales/ja-JP/chat.json +0 -4
- package/locales/ja-JP/components.json +5 -0
- package/locales/ko-KR/chat.json +0 -4
- package/locales/ko-KR/components.json +5 -0
- package/locales/nl-NL/chat.json +0 -4
- package/locales/nl-NL/components.json +5 -0
- package/locales/pl-PL/chat.json +0 -4
- package/locales/pl-PL/components.json +5 -0
- package/locales/pt-BR/chat.json +0 -4
- package/locales/pt-BR/components.json +5 -0
- package/locales/ru-RU/chat.json +0 -4
- package/locales/ru-RU/components.json +5 -0
- package/locales/tr-TR/chat.json +0 -4
- package/locales/tr-TR/components.json +5 -0
- package/locales/vi-VN/chat.json +0 -4
- package/locales/vi-VN/components.json +5 -0
- package/locales/zh-CN/chat.json +0 -4
- package/locales/zh-CN/components.json +5 -0
- package/locales/zh-TW/chat.json +0 -4
- package/locales/zh-TW/components.json +5 -0
- package/package.json +1 -1
- package/src/app/(main)/settings/provider/(detail)/doubao/page.tsx +40 -0
- package/src/app/(main)/settings/provider/features/ModelList/ModelConfigModal/index.tsx +1 -1
- package/src/components/Thinking/index.tsx +137 -0
- package/src/config/aiModels/doubao.ts +65 -0
- package/src/config/aiModels/index.ts +3 -0
- package/src/config/llm.ts +6 -0
- package/src/config/modelProviders/doubao.ts +23 -0
- package/src/config/modelProviders/index.ts +3 -0
- package/src/features/Conversation/Messages/Assistant/Reasoning/index.tsx +6 -110
- package/src/libs/agent-runtime/AgentRuntime.ts +7 -0
- package/src/libs/agent-runtime/doubao/index.ts +10 -0
- package/src/libs/agent-runtime/index.ts +1 -0
- package/src/libs/agent-runtime/types/type.ts +1 -0
- package/src/locales/default/chat.ts +0 -4
- package/src/locales/default/components.ts +5 -0
- package/src/server/globalConfig/index.ts +3 -0
- package/src/services/chat.ts +1 -1
- package/src/types/aiProvider.ts +1 -0
- package/src/types/user/settings/keyVaults.ts +1 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
import { AIChatModelCard } from '@/types/aiModel';
|
2
|
+
|
3
|
+
const doubaoChatModels: AIChatModelCard[] = [
|
4
|
+
{
|
5
|
+
contextWindowTokens: 4096,
|
6
|
+
description:
|
7
|
+
'拥有极致的响应速度,更好的性价比,为客户不同场景提供更灵活的选择。支持 4k 上下文窗口的推理和精调。',
|
8
|
+
displayName: 'Doubao Lite 4k',
|
9
|
+
enabled: true,
|
10
|
+
id: 'Doubao-lite-4k',
|
11
|
+
type: 'chat',
|
12
|
+
},
|
13
|
+
{
|
14
|
+
contextWindowTokens: 32_768,
|
15
|
+
description:
|
16
|
+
'拥有极致的响应速度,更好的性价比,为客户不同场景提供更灵活的选择。支持 32k 上下文窗口的推理和精调。',
|
17
|
+
displayName: 'Doubao Lite 32k',
|
18
|
+
enabled: true,
|
19
|
+
id: 'Doubao-lite-32k',
|
20
|
+
type: 'chat',
|
21
|
+
},
|
22
|
+
{
|
23
|
+
contextWindowTokens: 128_000,
|
24
|
+
description:
|
25
|
+
'拥有极致的响应速度,更好的性价比,为客户不同场景提供更灵活的选择。支持 128k 上下文窗口的推理和精调。',
|
26
|
+
displayName: 'Doubao Lite 128k',
|
27
|
+
enabled: true,
|
28
|
+
id: 'Doubao-lite-128k',
|
29
|
+
type: 'chat',
|
30
|
+
},
|
31
|
+
{
|
32
|
+
contextWindowTokens: 4096,
|
33
|
+
description:
|
34
|
+
'效果最好的主力模型,适合处理复杂任务,在参考问答、总结摘要、创作、文本分类、角色扮演等场景都有很好的效果。支持 4k 上下文窗口的推理和精调。',
|
35
|
+
displayName: 'Doubao Pro 4k',
|
36
|
+
enabled: true,
|
37
|
+
id: 'Doubao-pro-4k',
|
38
|
+
type: 'chat',
|
39
|
+
},
|
40
|
+
{
|
41
|
+
config: {
|
42
|
+
deploymentName: 'Doubao-pro-test',
|
43
|
+
},
|
44
|
+
contextWindowTokens: 32_768,
|
45
|
+
description:
|
46
|
+
'效果最好的主力模型,适合处理复杂任务,在参考问答、总结摘要、创作、文本分类、角色扮演等场景都有很好的效果。支持 32k 上下文窗口的推理和精调。',
|
47
|
+
displayName: 'Doubao Pro 32k',
|
48
|
+
enabled: true,
|
49
|
+
id: 'Doubao-pro-32k',
|
50
|
+
type: 'chat',
|
51
|
+
},
|
52
|
+
{
|
53
|
+
contextWindowTokens: 128_000,
|
54
|
+
description:
|
55
|
+
'效果最好的主力模型,适合处理复杂任务,在参考问答、总结摘要、创作、文本分类、角色扮演等场景都有很好的效果。支持 128k 上下文窗口的推理和精调。',
|
56
|
+
displayName: 'Doubao Pro 128k',
|
57
|
+
enabled: true,
|
58
|
+
id: 'Doubao-pro-128k',
|
59
|
+
type: 'chat',
|
60
|
+
},
|
61
|
+
];
|
62
|
+
|
63
|
+
export const allModels = [...doubaoChatModels];
|
64
|
+
|
65
|
+
export default allModels;
|
@@ -8,6 +8,7 @@ import { default as baichuan } from './baichuan';
|
|
8
8
|
import { default as bedrock } from './bedrock';
|
9
9
|
import { default as cloudflare } from './cloudflare';
|
10
10
|
import { default as deepseek } from './deepseek';
|
11
|
+
import { default as doubao } from './doubao';
|
11
12
|
import { default as fireworksai } from './fireworksai';
|
12
13
|
import { default as giteeai } from './giteeai';
|
13
14
|
import { default as github } from './github';
|
@@ -67,6 +68,7 @@ export const LOBE_DEFAULT_MODEL_LIST = buildDefaultModelList({
|
|
67
68
|
bedrock,
|
68
69
|
cloudflare,
|
69
70
|
deepseek,
|
71
|
+
doubao,
|
70
72
|
fireworksai,
|
71
73
|
giteeai,
|
72
74
|
github,
|
@@ -107,6 +109,7 @@ export { default as baichuan } from './baichuan';
|
|
107
109
|
export { default as bedrock } from './bedrock';
|
108
110
|
export { default as cloudflare } from './cloudflare';
|
109
111
|
export { default as deepseek } from './deepseek';
|
112
|
+
export { default as doubao } from './doubao';
|
110
113
|
export { default as fireworksai } from './fireworksai';
|
111
114
|
export { default as giteeai } from './giteeai';
|
112
115
|
export { default as github } from './github';
|
package/src/config/llm.ts
CHANGED
@@ -123,6 +123,9 @@ export const getLLMConfig = () => {
|
|
123
123
|
|
124
124
|
ENABLED_HIGRESS: z.boolean(),
|
125
125
|
HIGRESS_API_KEY: z.string().optional(),
|
126
|
+
|
127
|
+
ENABLED_DOUBAO: z.boolean(),
|
128
|
+
DOUBAO_API_KEY: z.string().optional(),
|
126
129
|
},
|
127
130
|
runtimeEnv: {
|
128
131
|
API_KEY_SELECT_MODE: process.env.API_KEY_SELECT_MODE,
|
@@ -244,6 +247,9 @@ export const getLLMConfig = () => {
|
|
244
247
|
|
245
248
|
ENABLED_HIGRESS: !!process.env.HIGRESS_API_KEY,
|
246
249
|
HIGRESS_API_KEY: process.env.HIGRESS_API_KEY,
|
250
|
+
|
251
|
+
ENABLED_DOUBAO: !!process.env.DOUBAO_API_KEY,
|
252
|
+
DOUBAO_API_KEY: process.env.DOUBAO_API_KEY,
|
247
253
|
},
|
248
254
|
});
|
249
255
|
};
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import { ModelProviderCard } from '@/types/llm';
|
2
|
+
|
3
|
+
// ref https://www.volcengine.com/docs/82379/1330310
|
4
|
+
const Doubao: ModelProviderCard = {
|
5
|
+
chatModels: [],
|
6
|
+
// checkModel: 'Doubao-lite-4k',
|
7
|
+
description: '字节跳动推出的自研大模型。通过字节跳动内部50+业务场景实践验证,每日万亿级tokens大使用量持续打磨,提供多种模态能力,以优质模型效果为企业打造丰富的业务体验。',
|
8
|
+
id: 'doubao',
|
9
|
+
modelsUrl: 'https://www.volcengine.com/product/doubao',
|
10
|
+
name: '豆包',
|
11
|
+
settings: {
|
12
|
+
disableBrowserRequest: true, // CORS error
|
13
|
+
sdkType: 'doubao',
|
14
|
+
// showModelFetcher: false,
|
15
|
+
smoothing: {
|
16
|
+
speed: 2,
|
17
|
+
text: true,
|
18
|
+
},
|
19
|
+
},
|
20
|
+
url: 'https://www.volcengine.com/product/doubao',
|
21
|
+
};
|
22
|
+
|
23
|
+
export default Doubao;
|
@@ -8,6 +8,7 @@ import BaichuanProvider from './baichuan';
|
|
8
8
|
import BedrockProvider from './bedrock';
|
9
9
|
import CloudflareProvider from './cloudflare';
|
10
10
|
import DeepSeekProvider from './deepseek';
|
11
|
+
import DoubaoProvider from './doubao';
|
11
12
|
import FireworksAIProvider from './fireworksai';
|
12
13
|
import GiteeAIProvider from './giteeai';
|
13
14
|
import GithubProvider from './github';
|
@@ -120,6 +121,7 @@ export const DEFAULT_MODEL_PROVIDER_LIST = [
|
|
120
121
|
GiteeAIProvider,
|
121
122
|
TaichuProvider,
|
122
123
|
Ai360Provider,
|
124
|
+
DoubaoProvider,
|
123
125
|
];
|
124
126
|
|
125
127
|
export const filterEnabledModels = (provider: ModelProviderCard) => {
|
@@ -139,6 +141,7 @@ export { default as BaichuanProviderCard } from './baichuan';
|
|
139
141
|
export { default as BedrockProviderCard } from './bedrock';
|
140
142
|
export { default as CloudflareProviderCard } from './cloudflare';
|
141
143
|
export { default as DeepSeekProviderCard } from './deepseek';
|
144
|
+
export { default as DoubaoProviderCard } from './doubao';
|
142
145
|
export { default as FireworksAIProviderCard } from './fireworksai';
|
143
146
|
export { default as GiteeAIProviderCard } from './giteeai';
|
144
147
|
export { default as GithubProviderCard } from './github';
|
@@ -1,123 +1,19 @@
|
|
1
|
-
import {
|
2
|
-
import { createStyles } from 'antd-style';
|
3
|
-
import { AtomIcon, ChevronDown, ChevronRight } from 'lucide-react';
|
4
|
-
import { rgba } from 'polished';
|
5
|
-
import { memo, useEffect, useState } from 'react';
|
6
|
-
import { useTranslation } from 'react-i18next';
|
7
|
-
import { Flexbox } from 'react-layout-kit';
|
1
|
+
import { memo } from 'react';
|
8
2
|
|
3
|
+
import Thinking from '@/components/Thinking';
|
9
4
|
import { useChatStore } from '@/store/chat';
|
10
5
|
import { aiChatSelectors } from '@/store/chat/selectors';
|
11
6
|
|
12
|
-
|
13
|
-
container: css`
|
14
|
-
cursor: pointer;
|
15
|
-
|
16
|
-
width: fit-content;
|
17
|
-
padding-block: 4px;
|
18
|
-
padding-inline: 8px;
|
19
|
-
border-radius: 6px;
|
20
|
-
|
21
|
-
color: ${token.colorTextTertiary};
|
22
|
-
|
23
|
-
&:hover {
|
24
|
-
background: ${isDarkMode ? token.colorFillQuaternary : token.colorFillTertiary};
|
25
|
-
}
|
26
|
-
`,
|
27
|
-
expand: css`
|
28
|
-
background: ${isDarkMode ? token.colorFillQuaternary : token.colorFillTertiary} !important;
|
29
|
-
`,
|
30
|
-
shinyText: css`
|
31
|
-
color: ${rgba(token.colorText, 0.45)};
|
32
|
-
|
33
|
-
background: linear-gradient(
|
34
|
-
120deg,
|
35
|
-
${rgba(token.colorTextBase, 0)} 40%,
|
36
|
-
${token.colorTextSecondary} 50%,
|
37
|
-
${rgba(token.colorTextBase, 0)} 60%
|
38
|
-
);
|
39
|
-
background-clip: text;
|
40
|
-
background-size: 200% 100%;
|
41
|
-
|
42
|
-
animation: shine 1.5s linear infinite;
|
43
|
-
|
44
|
-
@keyframes shine {
|
45
|
-
0% {
|
46
|
-
background-position: 100%;
|
47
|
-
}
|
48
|
-
|
49
|
-
100% {
|
50
|
-
background-position: -100%;
|
51
|
-
}
|
52
|
-
}
|
53
|
-
`,
|
54
|
-
title: css`
|
55
|
-
overflow: hidden;
|
56
|
-
display: -webkit-box;
|
57
|
-
-webkit-box-orient: vertical;
|
58
|
-
-webkit-line-clamp: 1;
|
59
|
-
|
60
|
-
font-size: 12px;
|
61
|
-
text-overflow: ellipsis;
|
62
|
-
`,
|
63
|
-
}));
|
64
|
-
|
65
|
-
interface ThinkingProps {
|
7
|
+
interface ReasoningProps {
|
66
8
|
content?: string;
|
67
9
|
duration?: number;
|
68
10
|
id: string;
|
69
11
|
}
|
70
12
|
|
71
|
-
const
|
72
|
-
const { t } = useTranslation('chat');
|
73
|
-
const { styles, cx } = useStyles();
|
74
|
-
|
75
|
-
const [showDetail, setShowDetail] = useState(false);
|
76
|
-
|
13
|
+
const Reasoning = memo<ReasoningProps>(({ content = '', duration, id }) => {
|
77
14
|
const isReasoning = useChatStore(aiChatSelectors.isMessageInReasoning(id));
|
78
15
|
|
79
|
-
|
80
|
-
if (isReasoning && !content) {
|
81
|
-
setShowDetail(true);
|
82
|
-
}
|
83
|
-
|
84
|
-
if (!isReasoning) {
|
85
|
-
setShowDetail(false);
|
86
|
-
}
|
87
|
-
}, [isReasoning, content]);
|
88
|
-
|
89
|
-
return (
|
90
|
-
<Flexbox
|
91
|
-
className={cx(styles.container, showDetail && styles.expand)}
|
92
|
-
gap={16}
|
93
|
-
onClick={() => {
|
94
|
-
setShowDetail(!showDetail);
|
95
|
-
}}
|
96
|
-
>
|
97
|
-
<Flexbox distribution={'space-between'} flex={1} horizontal>
|
98
|
-
{isReasoning ? (
|
99
|
-
<Flexbox gap={8} horizontal>
|
100
|
-
<Icon icon={AtomIcon} />
|
101
|
-
<Flexbox className={styles.shinyText} horizontal>
|
102
|
-
{t('reasoning.thinking')}
|
103
|
-
</Flexbox>
|
104
|
-
</Flexbox>
|
105
|
-
) : (
|
106
|
-
<Flexbox gap={8} horizontal>
|
107
|
-
<Icon icon={AtomIcon} />
|
108
|
-
{t('reasoning.thought', { duration: ((duration || 0) / 1000).toFixed(1) })}
|
109
|
-
</Flexbox>
|
110
|
-
)}
|
111
|
-
<Icon icon={showDetail ? ChevronDown : ChevronRight} />
|
112
|
-
</Flexbox>
|
113
|
-
|
114
|
-
{showDetail && (
|
115
|
-
<Flexbox>
|
116
|
-
<Markdown variant={'chat'}>{content}</Markdown>
|
117
|
-
</Flexbox>
|
118
|
-
)}
|
119
|
-
</Flexbox>
|
120
|
-
);
|
16
|
+
return <Thinking content={content} duration={duration} thinking={isReasoning} />;
|
121
17
|
});
|
122
18
|
|
123
|
-
export default
|
19
|
+
export default Reasoning;
|
@@ -11,6 +11,7 @@ import { LobeBaichuanAI } from './baichuan';
|
|
11
11
|
import { LobeBedrockAI, LobeBedrockAIParams } from './bedrock';
|
12
12
|
import { LobeCloudflareAI, LobeCloudflareParams } from './cloudflare';
|
13
13
|
import { LobeDeepSeekAI } from './deepseek';
|
14
|
+
import { LobeDoubaoAI } from './doubao';
|
14
15
|
import { LobeFireworksAI } from './fireworksai';
|
15
16
|
import { LobeGiteeAI } from './giteeai';
|
16
17
|
import { LobeGithubAI } from './github';
|
@@ -139,6 +140,7 @@ class AgentRuntime {
|
|
139
140
|
bedrock: Partial<LobeBedrockAIParams>;
|
140
141
|
cloudflare: Partial<LobeCloudflareParams>;
|
141
142
|
deepseek: Partial<ClientOptions>;
|
143
|
+
doubao: Partial<ClientOptions>;
|
142
144
|
fireworksai: Partial<ClientOptions>;
|
143
145
|
giteeai: Partial<ClientOptions>;
|
144
146
|
github: Partial<ClientOptions>;
|
@@ -363,6 +365,11 @@ class AgentRuntime {
|
|
363
365
|
runtimeModel = new LobeHigressAI(params.higress);
|
364
366
|
break;
|
365
367
|
}
|
368
|
+
|
369
|
+
case ModelProvider.Doubao: {
|
370
|
+
runtimeModel = new LobeDoubaoAI(params.doubao);
|
371
|
+
break;
|
372
|
+
}
|
366
373
|
}
|
367
374
|
return new AgentRuntime(runtimeModel);
|
368
375
|
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { ModelProvider } from '../types';
|
2
|
+
import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
|
3
|
+
|
4
|
+
export const LobeDoubaoAI = LobeOpenAICompatibleFactory({
|
5
|
+
baseURL: 'https://ark.cn-beijing.volces.com/api/v3',
|
6
|
+
debug: {
|
7
|
+
chatCompletion: () => process.env.DEBUG_DOUBAO_CHAT_COMPLETION === '1',
|
8
|
+
},
|
9
|
+
provider: ModelProvider.Doubao,
|
10
|
+
});
|
@@ -4,6 +4,7 @@ export { LobeAzureOpenAI } from './azureOpenai';
|
|
4
4
|
export * from './BaseAI';
|
5
5
|
export { LobeBedrockAI } from './bedrock';
|
6
6
|
export { LobeDeepSeekAI } from './deepseek';
|
7
|
+
export { LobeDoubaoAI } from './doubao';
|
7
8
|
export * from './error';
|
8
9
|
export { LobeGoogleAI } from './google';
|
9
10
|
export { LobeGroq } from './groq';
|
@@ -25,6 +25,9 @@ export const getServerGlobalConfig = () => {
|
|
25
25
|
enabledKey: 'ENABLED_AWS_BEDROCK',
|
26
26
|
modelListKey: 'AWS_BEDROCK_MODEL_LIST',
|
27
27
|
},
|
28
|
+
doubao: {
|
29
|
+
withDeploymentName: true,
|
30
|
+
},
|
28
31
|
giteeai: {
|
29
32
|
enabledKey: 'ENABLED_GITEE_AI',
|
30
33
|
modelListKey: 'GITEE_AI_MODEL_LIST',
|
package/src/services/chat.ts
CHANGED
@@ -221,7 +221,7 @@ class ChatService {
|
|
221
221
|
let model = res.model || DEFAULT_AGENT_CONFIG.model;
|
222
222
|
|
223
223
|
// if the provider is Azure, get the deployment name as the request model
|
224
|
-
if (provider === ModelProvider.Azure) {
|
224
|
+
if (provider === ModelProvider.Azure || provider === ModelProvider.Doubao) {
|
225
225
|
model = findAzureDeploymentName(model);
|
226
226
|
}
|
227
227
|
|
package/src/types/aiProvider.ts
CHANGED
@@ -39,6 +39,7 @@ export interface UserKeyVaults {
|
|
39
39
|
bedrock?: AWSBedrockKeyVault;
|
40
40
|
cloudflare?: CloudflareKeyVault;
|
41
41
|
deepseek?: OpenAICompatibleKeyVault;
|
42
|
+
doubao?: OpenAICompatibleKeyVault;
|
42
43
|
fireworksai?: OpenAICompatibleKeyVault;
|
43
44
|
giteeai?: OpenAICompatibleKeyVault;
|
44
45
|
github?: OpenAICompatibleKeyVault;
|