@lobehub/chat 1.49.15 → 1.50.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 +58 -0
- package/changelog/v1.json +21 -0
- package/docs/usage/agents/model.mdx +16 -0
- package/docs/usage/agents/model.zh-CN.mdx +16 -0
- package/locales/ar/discover.json +4 -0
- package/locales/ar/models.json +3 -0
- package/locales/ar/setting.json +12 -0
- package/locales/bg-BG/discover.json +4 -0
- package/locales/bg-BG/models.json +3 -0
- package/locales/bg-BG/setting.json +12 -0
- package/locales/de-DE/discover.json +4 -0
- package/locales/de-DE/models.json +3 -0
- package/locales/de-DE/setting.json +12 -0
- package/locales/en-US/discover.json +4 -0
- package/locales/en-US/models.json +3 -0
- package/locales/en-US/setting.json +12 -0
- package/locales/es-ES/discover.json +4 -0
- package/locales/es-ES/models.json +3 -0
- package/locales/es-ES/setting.json +12 -0
- package/locales/fa-IR/discover.json +4 -0
- package/locales/fa-IR/models.json +3 -0
- package/locales/fa-IR/setting.json +12 -0
- package/locales/fr-FR/discover.json +4 -0
- package/locales/fr-FR/models.json +3 -0
- package/locales/fr-FR/setting.json +12 -0
- package/locales/it-IT/discover.json +4 -0
- package/locales/it-IT/models.json +3 -0
- package/locales/it-IT/setting.json +12 -0
- package/locales/ja-JP/discover.json +4 -0
- package/locales/ja-JP/models.json +3 -0
- package/locales/ja-JP/setting.json +12 -0
- package/locales/ko-KR/discover.json +4 -0
- package/locales/ko-KR/models.json +15 -0
- package/locales/ko-KR/setting.json +12 -0
- package/locales/nl-NL/discover.json +4 -0
- package/locales/nl-NL/models.json +3 -0
- package/locales/nl-NL/setting.json +12 -0
- package/locales/pl-PL/discover.json +4 -0
- package/locales/pl-PL/models.json +3 -0
- package/locales/pl-PL/setting.json +12 -0
- package/locales/pt-BR/discover.json +4 -0
- package/locales/pt-BR/models.json +3 -0
- package/locales/pt-BR/setting.json +12 -0
- package/locales/ru-RU/discover.json +4 -0
- package/locales/ru-RU/models.json +3 -0
- package/locales/ru-RU/setting.json +12 -0
- package/locales/tr-TR/discover.json +4 -0
- package/locales/tr-TR/models.json +3 -0
- package/locales/tr-TR/setting.json +12 -0
- package/locales/vi-VN/discover.json +4 -0
- package/locales/vi-VN/models.json +3 -0
- package/locales/vi-VN/setting.json +12 -0
- package/locales/zh-CN/discover.json +4 -0
- package/locales/zh-CN/models.json +4 -1
- package/locales/zh-CN/setting.json +12 -0
- package/locales/zh-TW/discover.json +4 -0
- package/locales/zh-TW/models.json +3 -0
- package/locales/zh-TW/setting.json +12 -0
- package/package.json +1 -1
- package/src/app/(main)/discover/(detail)/model/[...slugs]/features/ParameterList/index.tsx +10 -0
- package/src/config/aiModels/github.ts +18 -7
- package/src/config/aiModels/openai.ts +35 -2
- package/src/config/aiModels/perplexity.ts +25 -32
- package/src/config/modelProviders/perplexity.ts +26 -32
- package/src/features/AgentSetting/AgentModal/index.tsx +27 -3
- package/src/libs/agent-runtime/github/index.ts +3 -3
- package/src/libs/agent-runtime/openai/index.ts +7 -5
- package/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap +7 -7
- package/src/libs/agent-runtime/utils/streams/openai.test.ts +202 -0
- package/src/libs/agent-runtime/utils/streams/openai.ts +9 -8
- package/src/locales/default/discover.ts +4 -0
- package/src/locales/default/setting.ts +12 -0
- package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +5 -0
- package/src/types/agent/index.ts +6 -0
- package/src/types/llm.ts +5 -0
@@ -2,62 +2,55 @@ import { AIChatModelCard } from '@/types/aiModel';
|
|
2
2
|
|
3
3
|
const perplexityChatModels: AIChatModelCard[] = [
|
4
4
|
{
|
5
|
-
contextWindowTokens:
|
5
|
+
contextWindowTokens: 127_072,
|
6
6
|
description:
|
7
|
-
'
|
8
|
-
displayName: '
|
9
|
-
enabled: true,
|
10
|
-
id: 'llama-3.1-sonar-small-128k-online',
|
11
|
-
type: 'chat',
|
12
|
-
},
|
13
|
-
{
|
14
|
-
contextWindowTokens: 128_000,
|
15
|
-
description:
|
16
|
-
'Llama 3.1 Sonar Large Online 模型,具备70B参数,支持约127,000个标记的上下文长度,适用于高容量和多样化聊天任务。',
|
17
|
-
displayName: 'Llama 3.1 Sonar Large Online',
|
7
|
+
'由 DeepSeek 推理模型提供支持的新 API 产品。',
|
8
|
+
displayName: 'Sonar Reasoning',
|
18
9
|
enabled: true,
|
19
|
-
id: '
|
10
|
+
id: 'sonar-reasoning',
|
20
11
|
type: 'chat',
|
21
12
|
},
|
22
13
|
{
|
23
|
-
contextWindowTokens:
|
14
|
+
contextWindowTokens: 200_000,
|
24
15
|
description:
|
25
|
-
'
|
26
|
-
displayName: '
|
16
|
+
'支持搜索上下文的高级搜索产品,支持高级查询和跟进。',
|
17
|
+
displayName: 'Sonar Pro',
|
27
18
|
enabled: true,
|
28
|
-
id: '
|
19
|
+
id: 'sonar-pro',
|
29
20
|
type: 'chat',
|
30
21
|
},
|
31
22
|
{
|
32
|
-
contextWindowTokens:
|
23
|
+
contextWindowTokens: 127_072,
|
33
24
|
description:
|
34
|
-
'
|
35
|
-
displayName: '
|
25
|
+
'基于搜索上下文的轻量级搜索产品,比 Sonar Pro 更快、更便宜。',
|
26
|
+
displayName: 'Sonar',
|
36
27
|
enabled: true,
|
37
|
-
id: '
|
28
|
+
id: 'sonar',
|
38
29
|
type: 'chat',
|
39
30
|
},
|
31
|
+
// The following will be deprecated on 02-22
|
40
32
|
{
|
41
|
-
contextWindowTokens:
|
33
|
+
contextWindowTokens: 127_072,
|
42
34
|
description:
|
43
|
-
'Llama 3.1 Sonar
|
44
|
-
displayName: 'Llama 3.1 Sonar
|
45
|
-
|
46
|
-
id: 'llama-3.1-sonar-large-128k-chat',
|
35
|
+
'Llama 3.1 Sonar Small Online 模型,具备8B参数,支持约127,000个标记的上下文长度,专为在线聊天设计,能高效处理各种文本交互。',
|
36
|
+
displayName: 'Llama 3.1 Sonar Small Online',
|
37
|
+
id: 'llama-3.1-sonar-small-128k-online',
|
47
38
|
type: 'chat',
|
48
39
|
},
|
49
40
|
{
|
50
|
-
contextWindowTokens:
|
41
|
+
contextWindowTokens: 127_072,
|
51
42
|
description:
|
52
|
-
'Llama 3.1
|
53
|
-
|
43
|
+
'Llama 3.1 Sonar Large Online 模型,具备70B参数,支持约127,000个标记的上下文长度,适用于高容量和多样化聊天任务。',
|
44
|
+
displayName: 'Llama 3.1 Sonar Large Online',
|
45
|
+
id: 'llama-3.1-sonar-large-128k-online',
|
54
46
|
type: 'chat',
|
55
47
|
},
|
56
48
|
{
|
57
|
-
contextWindowTokens:
|
49
|
+
contextWindowTokens: 127_072,
|
58
50
|
description:
|
59
|
-
'Llama 3.1
|
60
|
-
|
51
|
+
'Llama 3.1 Sonar Huge Online 模型,具备405B参数,支持约127,000个标记的上下文长度,设计用于复杂的在线聊天应用。',
|
52
|
+
displayName: 'Llama 3.1 Sonar Huge Online',
|
53
|
+
id: 'llama-3.1-sonar-huge-128k-online',
|
61
54
|
type: 'chat',
|
62
55
|
},
|
63
56
|
];
|
@@ -4,59 +4,53 @@ import { ModelProviderCard } from '@/types/llm';
|
|
4
4
|
const Perplexity: ModelProviderCard = {
|
5
5
|
chatModels: [
|
6
6
|
{
|
7
|
-
contextWindowTokens:
|
7
|
+
contextWindowTokens: 127_072,
|
8
8
|
description:
|
9
|
-
'
|
10
|
-
displayName: '
|
9
|
+
'由 DeepSeek 推理模型提供支持的新 API 产品。',
|
10
|
+
displayName: 'Sonar Reasoning',
|
11
11
|
enabled: true,
|
12
|
-
id: '
|
12
|
+
id: 'sonar-reasoning',
|
13
13
|
},
|
14
14
|
{
|
15
|
-
contextWindowTokens:
|
15
|
+
contextWindowTokens: 200_000,
|
16
16
|
description:
|
17
|
-
'
|
18
|
-
displayName: '
|
17
|
+
'支持搜索上下文的高级搜索产品,支持高级查询和跟进。',
|
18
|
+
displayName: 'Sonar Pro',
|
19
19
|
enabled: true,
|
20
|
-
id: '
|
20
|
+
id: 'sonar-pro',
|
21
21
|
},
|
22
22
|
{
|
23
|
-
contextWindowTokens:
|
23
|
+
contextWindowTokens: 127_072,
|
24
24
|
description:
|
25
|
-
'
|
26
|
-
displayName: '
|
25
|
+
'基于搜索上下文的轻量级搜索产品,比 Sonar Pro 更快、更便宜。',
|
26
|
+
displayName: 'Sonar',
|
27
27
|
enabled: true,
|
28
|
-
id: '
|
28
|
+
id: 'sonar',
|
29
29
|
},
|
30
|
+
// The following will be deprecated on 02-22
|
30
31
|
{
|
31
|
-
contextWindowTokens:
|
32
|
+
contextWindowTokens: 127_072,
|
32
33
|
description:
|
33
|
-
'Llama 3.1 Sonar Small
|
34
|
-
displayName: 'Llama 3.1 Sonar Small
|
35
|
-
|
36
|
-
id: 'llama-3.1-sonar-small-128k-chat',
|
37
|
-
},
|
38
|
-
{
|
39
|
-
contextWindowTokens: 128_000,
|
40
|
-
description:
|
41
|
-
'Llama 3.1 Sonar Large Chat 模型,具备70B参数,支持约127,000个标记的上下文长度,适合于复杂的离线聊天任务。',
|
42
|
-
displayName: 'Llama 3.1 Sonar Large Chat',
|
43
|
-
enabled: true,
|
44
|
-
id: 'llama-3.1-sonar-large-128k-chat',
|
34
|
+
'Llama 3.1 Sonar Small Online 模型,具备8B参数,支持约127,000个标记的上下文长度,专为在线聊天设计,能高效处理各种文本交互。',
|
35
|
+
displayName: 'Llama 3.1 Sonar Small Online',
|
36
|
+
id: 'llama-3.1-sonar-small-128k-online',
|
45
37
|
},
|
46
38
|
{
|
47
|
-
contextWindowTokens:
|
39
|
+
contextWindowTokens: 127_072,
|
48
40
|
description:
|
49
|
-
'Llama 3.1
|
50
|
-
|
41
|
+
'Llama 3.1 Sonar Large Online 模型,具备70B参数,支持约127,000个标记的上下文长度,适用于高容量和多样化聊天任务。',
|
42
|
+
displayName: 'Llama 3.1 Sonar Large Online',
|
43
|
+
id: 'llama-3.1-sonar-large-128k-online',
|
51
44
|
},
|
52
45
|
{
|
53
|
-
contextWindowTokens:
|
46
|
+
contextWindowTokens: 127_072,
|
54
47
|
description:
|
55
|
-
'Llama 3.1
|
56
|
-
|
48
|
+
'Llama 3.1 Sonar Huge Online 模型,具备405B参数,支持约127,000个标记的上下文长度,设计用于复杂的在线聊天应用。',
|
49
|
+
displayName: 'Llama 3.1 Sonar Huge Online',
|
50
|
+
id: 'llama-3.1-sonar-huge-128k-online',
|
57
51
|
},
|
58
52
|
],
|
59
|
-
checkModel: '
|
53
|
+
checkModel: 'sonar',
|
60
54
|
description:
|
61
55
|
'Perplexity 是一家领先的对话生成模型提供商,提供多种先进的Llama 3.1模型,支持在线和离线应用,特别适用于复杂的自然语言处理任务。',
|
62
56
|
id: 'perplexity',
|
@@ -1,7 +1,7 @@
|
|
1
1
|
'use client';
|
2
2
|
|
3
3
|
import { Form, ItemGroup, SliderWithInput } from '@lobehub/ui';
|
4
|
-
import { Switch } from 'antd';
|
4
|
+
import { Select, Switch } from 'antd';
|
5
5
|
import { memo } from 'react';
|
6
6
|
import { useTranslation } from 'react-i18next';
|
7
7
|
|
@@ -17,9 +17,9 @@ const AgentModal = memo(() => {
|
|
17
17
|
const { t } = useTranslation('setting');
|
18
18
|
const [form] = Form.useForm();
|
19
19
|
|
20
|
-
const [enableMaxTokens, updateConfig] = useStore((s) => {
|
20
|
+
const [enableMaxTokens, enableReasoningEffort, updateConfig] = useStore((s) => {
|
21
21
|
const config = selectors.chatConfig(s);
|
22
|
-
return [config.enableMaxTokens, s.setAgentConfig];
|
22
|
+
return [config.enableMaxTokens, config.enableReasoningEffort, s.setAgentConfig];
|
23
23
|
});
|
24
24
|
|
25
25
|
const providerName = useProviderName(useStore((s) => s.config.provider) as string);
|
@@ -79,6 +79,30 @@ const AgentModal = memo(() => {
|
|
79
79
|
name: ['params', 'max_tokens'],
|
80
80
|
tag: 'max_tokens',
|
81
81
|
},
|
82
|
+
{
|
83
|
+
children: <Switch />,
|
84
|
+
label: t('settingModel.enableReasoningEffort.title'),
|
85
|
+
minWidth: undefined,
|
86
|
+
name: ['chatConfig', 'enableReasoningEffort'],
|
87
|
+
valuePropName: 'checked',
|
88
|
+
},
|
89
|
+
{
|
90
|
+
children: (
|
91
|
+
<Select
|
92
|
+
defaultValue='medium'
|
93
|
+
options={[
|
94
|
+
{ label: t('settingModel.reasoningEffort.options.low'), value: 'low' },
|
95
|
+
{ label: t('settingModel.reasoningEffort.options.medium'), value: 'medium' },
|
96
|
+
{ label: t('settingModel.reasoningEffort.options.high'), value: 'high' },
|
97
|
+
]}
|
98
|
+
/>
|
99
|
+
),
|
100
|
+
desc: t('settingModel.reasoningEffort.desc'),
|
101
|
+
hidden: !enableReasoningEffort,
|
102
|
+
label: t('settingModel.reasoningEffort.title'),
|
103
|
+
name: ['params', 'reasoning_effort'],
|
104
|
+
tag: 'reasoning_effort',
|
105
|
+
},
|
82
106
|
],
|
83
107
|
title: t('settingModel.title'),
|
84
108
|
};
|
@@ -2,7 +2,7 @@ import { LOBE_DEFAULT_MODEL_LIST } from '@/config/modelProviders';
|
|
2
2
|
import type { ChatModelCard } from '@/types/llm';
|
3
3
|
|
4
4
|
import { AgentRuntimeErrorType } from '../error';
|
5
|
-
import {
|
5
|
+
import { pruneReasoningPayload, reasoningModels } from '../openai';
|
6
6
|
import { ModelProvider } from '../types';
|
7
7
|
import {
|
8
8
|
CHAT_MODELS_BLOCK_LIST,
|
@@ -37,8 +37,8 @@ export const LobeGithubAI = LobeOpenAICompatibleFactory({
|
|
37
37
|
handlePayload: (payload) => {
|
38
38
|
const { model } = payload;
|
39
39
|
|
40
|
-
if (
|
41
|
-
return { ...
|
40
|
+
if (reasoningModels.has(model)) {
|
41
|
+
return { ...pruneReasoningPayload(payload), stream: false } as any;
|
42
42
|
}
|
43
43
|
|
44
44
|
return { ...payload, stream: payload.stream ?? true };
|
@@ -2,21 +2,23 @@ import { ChatStreamPayload, ModelProvider, OpenAIChatMessage } from '../types';
|
|
2
2
|
import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
|
3
3
|
|
4
4
|
// TODO: 临时写法,后续要重构成 model card 展示配置
|
5
|
-
export const
|
5
|
+
export const reasoningModels = new Set([
|
6
6
|
'o1-preview',
|
7
7
|
'o1-preview-2024-09-12',
|
8
8
|
'o1-mini',
|
9
9
|
'o1-mini-2024-09-12',
|
10
10
|
'o1',
|
11
11
|
'o1-2024-12-17',
|
12
|
+
'o3-mini',
|
13
|
+
'o3-mini-2025-01-31',
|
12
14
|
]);
|
13
15
|
|
14
|
-
export const
|
16
|
+
export const pruneReasoningPayload = (payload: ChatStreamPayload) => ({
|
15
17
|
...payload,
|
16
18
|
frequency_penalty: 0,
|
17
19
|
messages: payload.messages.map((message: OpenAIChatMessage) => ({
|
18
20
|
...message,
|
19
|
-
role: message.role === 'system' ? '
|
21
|
+
role: message.role === 'system' ? 'developer' : message.role,
|
20
22
|
})),
|
21
23
|
presence_penalty: 0,
|
22
24
|
temperature: 1,
|
@@ -29,8 +31,8 @@ export const LobeOpenAI = LobeOpenAICompatibleFactory({
|
|
29
31
|
handlePayload: (payload) => {
|
30
32
|
const { model } = payload;
|
31
33
|
|
32
|
-
if (
|
33
|
-
return
|
34
|
+
if (reasoningModels.has(model)) {
|
35
|
+
return pruneReasoningPayload(payload) as any;
|
34
36
|
}
|
35
37
|
|
36
38
|
return { ...payload, stream: payload.stream ?? true };
|
@@ -196,7 +196,7 @@ _These are extended-context endpoints for [Hermes 3 405B Instruct](/models/nousr
|
|
196
196
|
"contextWindowTokens": 127072,
|
197
197
|
"description": "Llama 3.1 Sonar is Perplexity's latest model family. It surpasses their earlier Sonar models in cost-efficiency, speed, and performance. The model is built upon the Llama 3.1 405B and has internet access.",
|
198
198
|
"displayName": "Perplexity: Llama 3.1 Sonar 405B Online",
|
199
|
-
"enabled":
|
199
|
+
"enabled": false,
|
200
200
|
"functionCall": false,
|
201
201
|
"id": "perplexity/llama-3.1-sonar-huge-128k-online",
|
202
202
|
"maxTokens": undefined,
|
@@ -304,7 +304,7 @@ Note: This model is experimental and not suited for production use-cases. It may
|
|
304
304
|
|
305
305
|
This is the online version of the [offline chat model](/models/perplexity/llama-3.1-sonar-large-128k-chat). It is focused on delivering helpful, up-to-date, and factual responses. #online",
|
306
306
|
"displayName": "Perplexity: Llama 3.1 Sonar 70B Online",
|
307
|
-
"enabled":
|
307
|
+
"enabled": false,
|
308
308
|
"functionCall": false,
|
309
309
|
"id": "perplexity/llama-3.1-sonar-large-128k-online",
|
310
310
|
"maxTokens": undefined,
|
@@ -316,7 +316,7 @@ This is the online version of the [offline chat model](/models/perplexity/llama-
|
|
316
316
|
|
317
317
|
This is a normal offline LLM, but the [online version](/models/perplexity/llama-3.1-sonar-large-128k-online) of this model has Internet access.",
|
318
318
|
"displayName": "Perplexity: Llama 3.1 Sonar 70B",
|
319
|
-
"enabled":
|
319
|
+
"enabled": false,
|
320
320
|
"functionCall": false,
|
321
321
|
"id": "perplexity/llama-3.1-sonar-large-128k-chat",
|
322
322
|
"maxTokens": undefined,
|
@@ -328,7 +328,7 @@ This is a normal offline LLM, but the [online version](/models/perplexity/llama-
|
|
328
328
|
|
329
329
|
This is the online version of the [offline chat model](/models/perplexity/llama-3.1-sonar-small-128k-chat). It is focused on delivering helpful, up-to-date, and factual responses. #online",
|
330
330
|
"displayName": "Perplexity: Llama 3.1 Sonar 8B Online",
|
331
|
-
"enabled":
|
331
|
+
"enabled": false,
|
332
332
|
"functionCall": false,
|
333
333
|
"id": "perplexity/llama-3.1-sonar-small-128k-online",
|
334
334
|
"maxTokens": undefined,
|
@@ -340,7 +340,7 @@ This is the online version of the [offline chat model](/models/perplexity/llama-
|
|
340
340
|
|
341
341
|
This is a normal offline LLM, but the [online version](/models/perplexity/llama-3.1-sonar-small-128k-online) of this model has Internet access.",
|
342
342
|
"displayName": "Perplexity: Llama 3.1 Sonar 8B",
|
343
|
-
"enabled":
|
343
|
+
"enabled": false,
|
344
344
|
"functionCall": false,
|
345
345
|
"id": "perplexity/llama-3.1-sonar-small-128k-chat",
|
346
346
|
"maxTokens": undefined,
|
@@ -354,7 +354,7 @@ It has demonstrated strong performance compared to leading closed-source models
|
|
354
354
|
|
355
355
|
To read more about the model release, [click here](https://ai.meta.com/blog/meta-llama-3/). Usage of this model is subject to [Meta's Acceptable Use Policy](https://llama.meta.com/llama3/use-policy/).",
|
356
356
|
"displayName": "Meta: Llama 3.1 70B Instruct",
|
357
|
-
"enabled":
|
357
|
+
"enabled": true,
|
358
358
|
"functionCall": false,
|
359
359
|
"id": "meta-llama/llama-3.1-70b-instruct",
|
360
360
|
"maxTokens": undefined,
|
@@ -384,7 +384,7 @@ It has demonstrated strong performance compared to leading closed-source models
|
|
384
384
|
|
385
385
|
To read more about the model release, [click here](https://ai.meta.com/blog/meta-llama-3/). Usage of this model is subject to [Meta's Acceptable Use Policy](https://llama.meta.com/llama3/use-policy/).",
|
386
386
|
"displayName": "Meta: Llama 3.1 8B Instruct",
|
387
|
-
"enabled":
|
387
|
+
"enabled": true,
|
388
388
|
"functionCall": false,
|
389
389
|
"id": "meta-llama/llama-3.1-8b-instruct",
|
390
390
|
"maxTokens": undefined,
|
@@ -754,6 +754,7 @@ describe('OpenAIStream', () => {
|
|
754
754
|
].map((i) => `${i}\n`),
|
755
755
|
);
|
756
756
|
});
|
757
|
+
|
757
758
|
it('should handle reasoning in litellm', async () => {
|
758
759
|
const data = [
|
759
760
|
{
|
@@ -954,5 +955,206 @@ describe('OpenAIStream', () => {
|
|
954
955
|
].map((i) => `${i}\n`),
|
955
956
|
);
|
956
957
|
});
|
958
|
+
|
959
|
+
it('should handle reasoning in siliconflow', async () => {
|
960
|
+
const data = [
|
961
|
+
{
|
962
|
+
id: '1',
|
963
|
+
object: 'chat.completion.chunk',
|
964
|
+
created: 1737563070,
|
965
|
+
model: 'deepseek-reasoner',
|
966
|
+
system_fingerprint: 'fp_1c5d8833bc',
|
967
|
+
choices: [
|
968
|
+
{
|
969
|
+
index: 0,
|
970
|
+
delta: { role: 'assistant', reasoning_content: '', content: '' },
|
971
|
+
logprobs: null,
|
972
|
+
finish_reason: null,
|
973
|
+
},
|
974
|
+
],
|
975
|
+
},
|
976
|
+
{
|
977
|
+
id: '1',
|
978
|
+
object: 'chat.completion.chunk',
|
979
|
+
created: 1737563070,
|
980
|
+
model: 'deepseek-reasoner',
|
981
|
+
system_fingerprint: 'fp_1c5d8833bc',
|
982
|
+
choices: [
|
983
|
+
{
|
984
|
+
index: 0,
|
985
|
+
delta: { reasoning_content: '您好', content: '' },
|
986
|
+
logprobs: null,
|
987
|
+
finish_reason: null,
|
988
|
+
},
|
989
|
+
],
|
990
|
+
},
|
991
|
+
{
|
992
|
+
id: '1',
|
993
|
+
object: 'chat.completion.chunk',
|
994
|
+
created: 1737563070,
|
995
|
+
model: 'deepseek-reasoner',
|
996
|
+
system_fingerprint: 'fp_1c5d8833bc',
|
997
|
+
choices: [
|
998
|
+
{
|
999
|
+
index: 0,
|
1000
|
+
delta: { reasoning_content: '!', content: '' },
|
1001
|
+
logprobs: null,
|
1002
|
+
finish_reason: null,
|
1003
|
+
},
|
1004
|
+
],
|
1005
|
+
},
|
1006
|
+
{
|
1007
|
+
id: '1',
|
1008
|
+
object: 'chat.completion.chunk',
|
1009
|
+
created: 1737563070,
|
1010
|
+
model: 'deepseek-reasoner',
|
1011
|
+
system_fingerprint: 'fp_1c5d8833bc',
|
1012
|
+
choices: [
|
1013
|
+
{
|
1014
|
+
index: 0,
|
1015
|
+
delta: { content: '你好', reasoning_content: null },
|
1016
|
+
logprobs: null,
|
1017
|
+
finish_reason: null,
|
1018
|
+
},
|
1019
|
+
],
|
1020
|
+
},
|
1021
|
+
{
|
1022
|
+
id: '1',
|
1023
|
+
object: 'chat.completion.chunk',
|
1024
|
+
created: 1737563070,
|
1025
|
+
model: 'deepseek-reasoner',
|
1026
|
+
system_fingerprint: 'fp_1c5d8833bc',
|
1027
|
+
choices: [
|
1028
|
+
{
|
1029
|
+
index: 0,
|
1030
|
+
delta: { content: '很高兴', reasoning_cont: null },
|
1031
|
+
logprobs: null,
|
1032
|
+
finish_reason: null,
|
1033
|
+
},
|
1034
|
+
],
|
1035
|
+
},
|
1036
|
+
{
|
1037
|
+
id: '1',
|
1038
|
+
object: 'chat.completion.chunk',
|
1039
|
+
created: 1737563070,
|
1040
|
+
model: 'deepseek-reasoner',
|
1041
|
+
system_fingerprint: 'fp_1c5d8833bc',
|
1042
|
+
choices: [
|
1043
|
+
{
|
1044
|
+
index: 0,
|
1045
|
+
delta: { content: '为您', reasoning_content: null },
|
1046
|
+
logprobs: null,
|
1047
|
+
finish_reason: null,
|
1048
|
+
},
|
1049
|
+
],
|
1050
|
+
},
|
1051
|
+
{
|
1052
|
+
id: '1',
|
1053
|
+
object: 'chat.completion.chunk',
|
1054
|
+
created: 1737563070,
|
1055
|
+
model: 'deepseek-reasoner',
|
1056
|
+
system_fingerprint: 'fp_1c5d8833bc',
|
1057
|
+
choices: [
|
1058
|
+
{
|
1059
|
+
index: 0,
|
1060
|
+
delta: { content: '提供', reasoning_content: null },
|
1061
|
+
logprobs: null,
|
1062
|
+
finish_reason: null,
|
1063
|
+
},
|
1064
|
+
],
|
1065
|
+
},
|
1066
|
+
{
|
1067
|
+
id: '1',
|
1068
|
+
object: 'chat.completion.chunk',
|
1069
|
+
created: 1737563070,
|
1070
|
+
model: 'deepseek-reasoner',
|
1071
|
+
system_fingerprint: 'fp_1c5d8833bc',
|
1072
|
+
choices: [
|
1073
|
+
{
|
1074
|
+
index: 0,
|
1075
|
+
delta: { content: '帮助。', reasoning_content: null },
|
1076
|
+
logprobs: null,
|
1077
|
+
finish_reason: null,
|
1078
|
+
},
|
1079
|
+
],
|
1080
|
+
},
|
1081
|
+
{
|
1082
|
+
id: '1',
|
1083
|
+
object: 'chat.completion.chunk',
|
1084
|
+
created: 1737563070,
|
1085
|
+
model: 'deepseek-reasoner',
|
1086
|
+
system_fingerprint: 'fp_1c5d8833bc',
|
1087
|
+
choices: [
|
1088
|
+
{
|
1089
|
+
index: 0,
|
1090
|
+
delta: { content: '', reasoning_content: null },
|
1091
|
+
logprobs: null,
|
1092
|
+
finish_reason: 'stop',
|
1093
|
+
},
|
1094
|
+
],
|
1095
|
+
usage: {
|
1096
|
+
prompt_tokens: 6,
|
1097
|
+
completion_tokens: 104,
|
1098
|
+
total_tokens: 110,
|
1099
|
+
prompt_tokens_details: { cached_tokens: 0 },
|
1100
|
+
completion_tokens_details: { reasoning_tokens: 70 },
|
1101
|
+
prompt_cache_hit_tokens: 0,
|
1102
|
+
prompt_cache_miss_tokens: 6,
|
1103
|
+
},
|
1104
|
+
},
|
1105
|
+
];
|
1106
|
+
|
1107
|
+
const mockOpenAIStream = new ReadableStream({
|
1108
|
+
start(controller) {
|
1109
|
+
data.forEach((chunk) => {
|
1110
|
+
controller.enqueue(chunk);
|
1111
|
+
});
|
1112
|
+
|
1113
|
+
controller.close();
|
1114
|
+
},
|
1115
|
+
});
|
1116
|
+
|
1117
|
+
const protocolStream = OpenAIStream(mockOpenAIStream);
|
1118
|
+
|
1119
|
+
const decoder = new TextDecoder();
|
1120
|
+
const chunks = [];
|
1121
|
+
|
1122
|
+
// @ts-ignore
|
1123
|
+
for await (const chunk of protocolStream) {
|
1124
|
+
chunks.push(decoder.decode(chunk, { stream: true }));
|
1125
|
+
}
|
1126
|
+
|
1127
|
+
expect(chunks).toEqual(
|
1128
|
+
[
|
1129
|
+
'id: 1',
|
1130
|
+
'event: reasoning',
|
1131
|
+
`data: ""\n`,
|
1132
|
+
'id: 1',
|
1133
|
+
'event: reasoning',
|
1134
|
+
`data: "您好"\n`,
|
1135
|
+
'id: 1',
|
1136
|
+
'event: reasoning',
|
1137
|
+
`data: "!"\n`,
|
1138
|
+
'id: 1',
|
1139
|
+
'event: text',
|
1140
|
+
`data: "你好"\n`,
|
1141
|
+
'id: 1',
|
1142
|
+
'event: text',
|
1143
|
+
`data: "很高兴"\n`,
|
1144
|
+
'id: 1',
|
1145
|
+
'event: text',
|
1146
|
+
`data: "为您"\n`,
|
1147
|
+
'id: 1',
|
1148
|
+
'event: text',
|
1149
|
+
`data: "提供"\n`,
|
1150
|
+
'id: 1',
|
1151
|
+
'event: text',
|
1152
|
+
`data: "帮助。"\n`,
|
1153
|
+
'id: 1',
|
1154
|
+
'event: stop',
|
1155
|
+
`data: "stop"\n`,
|
1156
|
+
].map((i) => `${i}\n`),
|
1157
|
+
);
|
1158
|
+
});
|
957
1159
|
});
|
958
1160
|
});
|
@@ -37,9 +37,8 @@ export const transformOpenAIStream = (
|
|
37
37
|
return { data: errorData, id: 'first_chunk_error', type: 'error' };
|
38
38
|
}
|
39
39
|
|
40
|
-
// maybe need another structure to add support for multiple choices
|
41
|
-
|
42
40
|
try {
|
41
|
+
// maybe need another structure to add support for multiple choices
|
43
42
|
const item = chunk.choices[0];
|
44
43
|
if (!item) {
|
45
44
|
return { data: chunk, id: chunk.id, type: 'data' };
|
@@ -88,12 +87,10 @@ export const transformOpenAIStream = (
|
|
88
87
|
return { data: item.finish_reason, id: chunk.id, type: 'stop' };
|
89
88
|
}
|
90
89
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
// DeepSeek reasoner 会将 thinking 放在 reasoning_content 字段中
|
96
|
-
// litellm 处理 reasoning content 时 不会设定 content = null
|
90
|
+
// DeepSeek reasoner will put thinking in the reasoning_content field
|
91
|
+
// litellm will not set content = null when processing reasoning content
|
92
|
+
// en: siliconflow has encountered a situation where both content and reasoning_content are present, so the parsing order go ahead
|
93
|
+
// refs: https://github.com/lobehub/lobe-chat/issues/5681
|
97
94
|
if (
|
98
95
|
item.delta &&
|
99
96
|
'reasoning_content' in item.delta &&
|
@@ -102,6 +99,10 @@ export const transformOpenAIStream = (
|
|
102
99
|
return { data: item.delta.reasoning_content, id: chunk.id, type: 'reasoning' };
|
103
100
|
}
|
104
101
|
|
102
|
+
if (typeof item.delta?.content === 'string') {
|
103
|
+
return { data: item.delta.content, id: chunk.id, type: 'text' };
|
104
|
+
}
|
105
|
+
|
105
106
|
// 无内容情况
|
106
107
|
if (item.delta && item.delta.content === null) {
|
107
108
|
return { data: item.delta, id: chunk.id, type: 'data' };
|
@@ -127,6 +127,10 @@ export default {
|
|
127
127
|
title: '话题新鲜度',
|
128
128
|
},
|
129
129
|
range: '范围',
|
130
|
+
reasoning_effort: {
|
131
|
+
desc: '此设置用于控制模型在生成回答前的推理强度。低强度优先响应速度并节省 Token,高强度提供更完整的推理,但会消耗更多 Token 并降低响应速度。默认值为中,平衡推理准确性与响应速度。',
|
132
|
+
title: '推理强度',
|
133
|
+
},
|
130
134
|
temperature: {
|
131
135
|
desc: '此设置影响模型回应的多样性。较低的值会导致更可预测和典型的回应,而较高的值则鼓励更多样化和不常见的回应。当值设为0时,模型对于给定的输入总是给出相同的回应。',
|
132
136
|
title: '随机性',
|
@@ -202,6 +202,9 @@ export default {
|
|
202
202
|
enableMaxTokens: {
|
203
203
|
title: '开启单次回复限制',
|
204
204
|
},
|
205
|
+
enableReasoningEffort: {
|
206
|
+
title: '开启推理强度调整',
|
207
|
+
},
|
205
208
|
frequencyPenalty: {
|
206
209
|
desc: '值越大,越有可能降低重复字词',
|
207
210
|
title: '频率惩罚度',
|
@@ -218,6 +221,15 @@ export default {
|
|
218
221
|
desc: '值越大,越有可能扩展到新话题',
|
219
222
|
title: '话题新鲜度',
|
220
223
|
},
|
224
|
+
reasoningEffort: {
|
225
|
+
desc: '值越大,推理能力越强,但可能会增加响应时间和 Token 消耗',
|
226
|
+
options: {
|
227
|
+
high: '高',
|
228
|
+
low: '低',
|
229
|
+
medium: '中',
|
230
|
+
},
|
231
|
+
title: '推理强度',
|
232
|
+
},
|
221
233
|
temperature: {
|
222
234
|
desc: '值越大,回复越随机',
|
223
235
|
title: '随机性',
|
@@ -421,6 +421,11 @@ export const generateAIChat: StateCreator<
|
|
421
421
|
? agentConfig.params.max_tokens
|
422
422
|
: undefined;
|
423
423
|
|
424
|
+
// 5. handle reasoning_effort
|
425
|
+
agentConfig.params.reasoning_effort = chatConfig.enableReasoningEffort
|
426
|
+
? agentConfig.params.reasoning_effort
|
427
|
+
: undefined;
|
428
|
+
|
424
429
|
let isFunctionCall = false;
|
425
430
|
let msgTraceId: string | undefined;
|
426
431
|
let output = '';
|