@lobehub/chat 1.68.11 → 1.69.1
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/locales/ar/chat.json +8 -0
- package/locales/bg-BG/chat.json +8 -0
- package/locales/de-DE/chat.json +8 -0
- package/locales/en-US/chat.json +8 -0
- package/locales/es-ES/chat.json +8 -0
- package/locales/fa-IR/chat.json +8 -0
- package/locales/fr-FR/chat.json +8 -0
- package/locales/it-IT/chat.json +8 -0
- package/locales/ja-JP/chat.json +8 -0
- package/locales/ko-KR/chat.json +8 -0
- package/locales/nl-NL/chat.json +8 -0
- package/locales/pl-PL/chat.json +8 -0
- package/locales/pt-BR/chat.json +8 -0
- package/locales/ru-RU/chat.json +8 -0
- package/locales/tr-TR/chat.json +8 -0
- package/locales/vi-VN/chat.json +8 -0
- package/locales/zh-CN/chat.json +8 -0
- package/locales/zh-TW/chat.json +8 -0
- package/next.config.ts +6 -0
- package/package.json +1 -1
- package/packages/web-crawler/src/crawImpl/naive.ts +19 -12
- package/packages/web-crawler/src/urlRules.ts +9 -1
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/index.tsx +9 -18
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/WelcomeMessage.tsx +2 -5
- package/src/app/[variants]/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/HeaderAction.tsx +3 -2
- package/src/app/[variants]/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/Main.tsx +56 -30
- package/src/app/[variants]/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/Tags/HistoryLimitTags.tsx +26 -0
- package/src/app/[variants]/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/{SearchTags.tsx → Tags/SearchTags.tsx} +7 -4
- package/src/app/[variants]/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/{Tags.tsx → Tags/index.tsx} +4 -1
- package/src/app/[variants]/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/index.tsx +1 -1
- package/src/config/aiModels/anthropic.ts +16 -1
- package/src/config/aiModels/google.ts +0 -1
- package/src/config/aiModels/groq.ts +14 -0
- package/src/config/aiModels/novita.ts +36 -0
- package/src/config/aiModels/siliconcloud.ts +18 -2
- package/src/config/modelProviders/anthropic.ts +0 -2
- package/src/const/layoutTokens.test.ts +1 -1
- package/src/const/layoutTokens.ts +1 -1
- package/src/const/models.ts +27 -0
- package/src/features/ChatInput/ActionBar/History.tsx +6 -3
- package/src/features/ChatInput/ActionBar/Model/ContextCachingSwitch.tsx +20 -0
- package/src/features/ChatInput/ActionBar/Model/ControlsForm.tsx +49 -7
- package/src/features/ChatInput/ActionBar/Model/ReasoningTokenSlider.tsx +6 -14
- package/src/features/ChatInput/ActionBar/Search/ModelBuiltinSearch.tsx +2 -2
- package/src/features/ChatInput/ActionBar/Search/SwitchPanel.tsx +2 -2
- package/src/features/ChatInput/ActionBar/Token/TokenTag.tsx +3 -5
- package/src/features/Conversation/Messages/Assistant/Tool/Render/CustomRender.tsx +2 -0
- package/src/features/Conversation/Messages/Assistant/Tool/Render/index.tsx +5 -1
- package/src/features/Conversation/Messages/Assistant/Tool/index.tsx +2 -0
- package/src/features/Conversation/components/ChatItem/index.tsx +3 -6
- package/src/features/Portal/Thread/Chat/ChatItem.tsx +4 -9
- package/src/hooks/useAgentEnableSearch.ts +2 -2
- package/src/libs/agent-runtime/anthropic/index.test.ts +36 -7
- package/src/libs/agent-runtime/anthropic/index.ts +30 -8
- package/src/libs/agent-runtime/azureOpenai/index.ts +4 -9
- package/src/libs/agent-runtime/azureai/index.ts +4 -9
- package/src/libs/agent-runtime/openai/index.ts +21 -38
- package/src/libs/agent-runtime/types/chat.ts +4 -0
- package/src/libs/agent-runtime/utils/anthropicHelpers.test.ts +55 -0
- package/src/libs/agent-runtime/utils/anthropicHelpers.ts +37 -3
- package/src/libs/langchain/loaders/code/__tests__/long.json +2 -2
- package/src/libs/langchain/loaders/code/__tests__/long.txt +1 -1
- package/src/locales/default/chat.ts +8 -0
- package/src/store/agent/initialState.ts +2 -2
- package/src/store/agent/selectors.ts +1 -1
- package/src/store/agent/slices/chat/{selectors.test.ts → selectors/agent.test.ts} +2 -2
- package/src/store/agent/slices/chat/{selectors.ts → selectors/agent.ts} +24 -33
- package/src/store/agent/slices/chat/selectors/chatConfig.test.ts +184 -0
- package/src/store/agent/slices/chat/selectors/chatConfig.ts +65 -0
- package/src/store/agent/slices/chat/selectors/index.ts +2 -0
- package/src/store/agent/store.ts +2 -2
- package/src/store/chat/helpers.test.ts +7 -7
- package/src/store/chat/helpers.ts +11 -7
- package/src/store/chat/slices/aiChat/actions/__tests__/generateAIChat.test.ts +3 -3
- package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +11 -2
- package/src/store/chat/slices/aiChat/actions/helpers.ts +6 -2
- package/src/store/chat/slices/builtinTool/actions/searXNG.ts +28 -20
- package/src/store/chat/slices/message/selectors.ts +7 -3
- package/src/store/chat/slices/thread/selectors/index.ts +7 -3
- package/src/tools/web-browsing/Render/PageContent/Result.tsx +4 -2
- package/src/tools/web-browsing/Render/index.tsx +2 -0
- package/src/types/agent/index.ts +4 -0
- package/src/types/aiModel.ts +1 -1
- package/src/types/aiProvider.ts +60 -31
- /package/packages/web-crawler/src/{__test__ → __tests__}/crawler.test.ts +0 -0
- /package/packages/web-crawler/src/crawImpl/{__test__ → __tests__}/jina.test.ts +0 -0
- /package/src/app/[variants]/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/{KnowledgeTag.tsx → Tags/KnowledgeTag.tsx} +0 -0
- /package/src/store/agent/slices/chat/{__snapshots__/selectors.test.ts.snap → selectors/__snapshots__/agent.test.ts.snap} +0 -0
@@ -4,7 +4,7 @@ import React from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
5
5
|
|
6
6
|
import { useAgentStore } from '@/store/agent';
|
7
|
-
import {
|
7
|
+
import { agentChatConfigSelectors } from '@/store/agent/selectors';
|
8
8
|
import { useChatStore } from '@/store/chat';
|
9
9
|
import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
|
10
10
|
import { useSessionStore } from '@/store/session';
|
@@ -12,10 +12,7 @@ import { sessionMetaSelectors } from '@/store/session/selectors';
|
|
12
12
|
|
13
13
|
const WelcomeMessage = () => {
|
14
14
|
const { t } = useTranslation('chat');
|
15
|
-
const
|
16
|
-
const config = agentSelectors.currentAgentChatConfig(s);
|
17
|
-
return [config.displayMode];
|
18
|
-
});
|
15
|
+
const type = useAgentStore(agentChatConfigSelectors.displayMode);
|
19
16
|
|
20
17
|
const meta = useSessionStore(sessionMetaSelectors.currentAgentMeta, isEqual);
|
21
18
|
const { isAgentEditable } = useServerConfigStore(featureFlagsSelectors);
|
package/src/app/[variants]/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/HeaderAction.tsx
CHANGED
@@ -4,6 +4,7 @@ import { ActionIcon } from '@lobehub/ui';
|
|
4
4
|
import { PanelRightClose, PanelRightOpen } from 'lucide-react';
|
5
5
|
import { memo } from 'react';
|
6
6
|
import { useTranslation } from 'react-i18next';
|
7
|
+
import { Flexbox } from 'react-layout-kit';
|
7
8
|
|
8
9
|
import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens';
|
9
10
|
import { useGlobalStore } from '@/store/global';
|
@@ -24,7 +25,7 @@ const HeaderAction = memo(() => {
|
|
24
25
|
const { isAgentEditable } = useServerConfigStore(featureFlagsSelectors);
|
25
26
|
|
26
27
|
return (
|
27
|
-
|
28
|
+
<Flexbox gap={4} horizontal>
|
28
29
|
<ShareButton />
|
29
30
|
<ActionIcon
|
30
31
|
icon={showAgentSettings ? PanelRightClose : PanelRightOpen}
|
@@ -33,7 +34,7 @@ const HeaderAction = memo(() => {
|
|
33
34
|
title={t('roleAndArchive')}
|
34
35
|
/>
|
35
36
|
{isAgentEditable && <SettingButton />}
|
36
|
-
|
37
|
+
</Flexbox>
|
37
38
|
);
|
38
39
|
});
|
39
40
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
'use client';
|
2
2
|
|
3
3
|
import { ActionIcon, Avatar } from '@lobehub/ui';
|
4
|
-
import { ChatHeaderTitle } from '@lobehub/ui/chat';
|
5
4
|
import { Skeleton } from 'antd';
|
5
|
+
import { createStyles } from 'antd-style';
|
6
6
|
import { PanelLeftClose, PanelLeftOpen } from 'lucide-react';
|
7
7
|
import { parseAsBoolean, useQueryState } from 'nuqs';
|
8
8
|
import { Suspense, memo } from 'react';
|
@@ -19,17 +19,38 @@ import { sessionMetaSelectors, sessionSelectors } from '@/store/session/selector
|
|
19
19
|
|
20
20
|
import Tags from './Tags';
|
21
21
|
|
22
|
+
const useStyles = createStyles(({ css }) => ({
|
23
|
+
container: css`
|
24
|
+
position: relative;
|
25
|
+
overflow: hidden;
|
26
|
+
flex: 1;
|
27
|
+
max-width: 100%;
|
28
|
+
`,
|
29
|
+
tag: css`
|
30
|
+
flex: none;
|
31
|
+
align-items: baseline;
|
32
|
+
`,
|
33
|
+
title: css`
|
34
|
+
overflow: hidden;
|
35
|
+
|
36
|
+
font-size: 14px;
|
37
|
+
font-weight: bold;
|
38
|
+
line-height: 1;
|
39
|
+
text-overflow: ellipsis;
|
40
|
+
white-space: nowrap;
|
41
|
+
`,
|
42
|
+
}));
|
43
|
+
|
22
44
|
const Main = memo(() => {
|
23
45
|
const { t } = useTranslation('chat');
|
24
|
-
|
46
|
+
const { styles } = useStyles();
|
25
47
|
useInitAgentConfig();
|
26
48
|
const [isPinned] = useQueryState('pinned', parseAsBoolean);
|
27
49
|
|
28
|
-
const [init, isInbox, title,
|
50
|
+
const [init, isInbox, title, avatar, backgroundColor] = useSessionStore((s) => [
|
29
51
|
sessionSelectors.isSomeSessionActive(s),
|
30
52
|
sessionSelectors.isInboxSession(s),
|
31
53
|
sessionMetaSelectors.currentAgentTitle(s),
|
32
|
-
sessionMetaSelectors.currentAgentDescription(s),
|
33
54
|
sessionMetaSelectors.currentAgentAvatar(s),
|
34
55
|
sessionMetaSelectors.currentAgentBackgroundColor(s),
|
35
56
|
]);
|
@@ -37,34 +58,36 @@ const Main = memo(() => {
|
|
37
58
|
const openChatSettings = useOpenChatSettings();
|
38
59
|
|
39
60
|
const displayTitle = isInbox ? t('inbox.title') : title;
|
40
|
-
const displayDesc = isInbox ? t('inbox.desc') : description;
|
41
61
|
const showSessionPanel = useGlobalStore(systemStatusSelectors.showSessionPanel);
|
42
62
|
const updateSystemStatus = useGlobalStore((s) => s.updateSystemStatus);
|
43
63
|
|
44
|
-
|
45
|
-
|
46
|
-
{
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
64
|
+
if (!init)
|
65
|
+
return (
|
66
|
+
<Flexbox align={'center'} gap={8} horizontal>
|
67
|
+
{!isPinned && (
|
68
|
+
<ActionIcon
|
69
|
+
aria-label={t('agents')}
|
70
|
+
icon={showSessionPanel ? PanelLeftClose : PanelLeftOpen}
|
71
|
+
onClick={() => {
|
72
|
+
updateSystemStatus({
|
73
|
+
sessionsWidth: showSessionPanel ? 0 : 320,
|
74
|
+
showSessionPanel: !showSessionPanel,
|
75
|
+
});
|
76
|
+
}}
|
77
|
+
size={DESKTOP_HEADER_ICON_SIZE}
|
78
|
+
title={t('agents')}
|
79
|
+
/>
|
80
|
+
)}
|
81
|
+
<Skeleton
|
82
|
+
active
|
83
|
+
avatar={{ shape: 'circle', size: 28 }}
|
84
|
+
paragraph={false}
|
85
|
+
title={{ style: { margin: 0, marginTop: 4 }, width: 200 }}
|
58
86
|
/>
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
paragraph={false}
|
64
|
-
title={{ style: { margin: 0, marginTop: 8 }, width: 200 }}
|
65
|
-
/>
|
66
|
-
</Flexbox>
|
67
|
-
) : (
|
87
|
+
</Flexbox>
|
88
|
+
);
|
89
|
+
|
90
|
+
return (
|
68
91
|
<Flexbox align={'center'} gap={4} horizontal>
|
69
92
|
{!isPinned && (
|
70
93
|
<ActionIcon
|
@@ -84,10 +107,13 @@ const Main = memo(() => {
|
|
84
107
|
avatar={avatar}
|
85
108
|
background={backgroundColor}
|
86
109
|
onClick={() => openChatSettings()}
|
87
|
-
size={
|
110
|
+
size={32}
|
88
111
|
title={title}
|
89
112
|
/>
|
90
|
-
<
|
113
|
+
<Flexbox align={'center'} className={styles.container} gap={8} horizontal>
|
114
|
+
<div className={styles.title}>{displayTitle}</div>
|
115
|
+
<Tags />
|
116
|
+
</Flexbox>
|
91
117
|
</Flexbox>
|
92
118
|
);
|
93
119
|
});
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { Icon, Tag, Tooltip } from '@lobehub/ui';
|
2
|
+
import { HistoryIcon } from 'lucide-react';
|
3
|
+
import { memo } from 'react';
|
4
|
+
import { useTranslation } from 'react-i18next';
|
5
|
+
import { Flexbox } from 'react-layout-kit';
|
6
|
+
|
7
|
+
import { useAgentStore } from '@/store/agent';
|
8
|
+
import { agentChatConfigSelectors } from '@/store/agent/selectors';
|
9
|
+
|
10
|
+
const SearchTag = memo(() => {
|
11
|
+
const { t } = useTranslation('chat');
|
12
|
+
const historyCount = useAgentStore(agentChatConfigSelectors.historyCount);
|
13
|
+
|
14
|
+
return (
|
15
|
+
<Tooltip title={t('history.title', { count: historyCount })}>
|
16
|
+
<Flexbox height={22}>
|
17
|
+
<Tag>
|
18
|
+
<Icon icon={HistoryIcon} />
|
19
|
+
<span>{historyCount}</span>
|
20
|
+
</Tag>
|
21
|
+
</Flexbox>
|
22
|
+
</Tooltip>
|
23
|
+
);
|
24
|
+
});
|
25
|
+
|
26
|
+
export default SearchTag;
|
@@ -2,15 +2,18 @@ import { Icon, Tag } from '@lobehub/ui';
|
|
2
2
|
import { Globe } from 'lucide-react';
|
3
3
|
import { memo } from 'react';
|
4
4
|
import { useTranslation } from 'react-i18next';
|
5
|
+
import { Flexbox } from 'react-layout-kit';
|
5
6
|
|
6
7
|
const SearchTag = memo(() => {
|
7
8
|
const { t } = useTranslation('chat');
|
8
9
|
|
9
10
|
return (
|
10
|
-
<
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
<Flexbox height={22}>
|
12
|
+
<Tag>
|
13
|
+
{<Icon icon={Globe} />}
|
14
|
+
<div>{t('search.title')}</div>
|
15
|
+
</Tag>
|
16
|
+
</Flexbox>
|
14
17
|
);
|
15
18
|
});
|
16
19
|
|
@@ -9,12 +9,13 @@ import PluginTag from '@/features/PluginTag';
|
|
9
9
|
import { useAgentEnableSearch } from '@/hooks/useAgentEnableSearch';
|
10
10
|
import { useModelSupportToolUse } from '@/hooks/useModelSupportToolUse';
|
11
11
|
import { useAgentStore } from '@/store/agent';
|
12
|
-
import { agentSelectors } from '@/store/agent/selectors';
|
12
|
+
import { agentChatConfigSelectors, agentSelectors } from '@/store/agent/selectors';
|
13
13
|
import { useUserStore } from '@/store/user';
|
14
14
|
import { authSelectors } from '@/store/user/selectors';
|
15
15
|
|
16
16
|
import KnowledgeTag from './KnowledgeTag';
|
17
17
|
import SearchTags from './SearchTags';
|
18
|
+
import HistoryLimitTags from './HistoryLimitTags';
|
18
19
|
|
19
20
|
const TitleTags = memo(() => {
|
20
21
|
const [model, provider, hasKnowledge, isLoading] = useAgentStore((s) => [
|
@@ -26,6 +27,7 @@ const TitleTags = memo(() => {
|
|
26
27
|
|
27
28
|
const plugins = useAgentStore(agentSelectors.currentAgentPlugins, isEqual);
|
28
29
|
const enabledKnowledge = useAgentStore(agentSelectors.currentEnabledKnowledge, isEqual);
|
30
|
+
const enableHistoryCount = useAgentStore(agentChatConfigSelectors.enableHistoryCount);
|
29
31
|
|
30
32
|
const showPlugin = useModelSupportToolUse(model, provider);
|
31
33
|
const isLogin = useUserStore(authSelectors.isLogin);
|
@@ -42,6 +44,7 @@ const TitleTags = memo(() => {
|
|
42
44
|
{isAgentEnableSearch && <SearchTags />}
|
43
45
|
{showPlugin && plugins?.length > 0 && <PluginTag plugins={plugins} />}
|
44
46
|
{hasKnowledge && <KnowledgeTag data={enabledKnowledge} />}
|
47
|
+
{enableHistoryCount && <HistoryLimitTags />}
|
45
48
|
</Flexbox>
|
46
49
|
);
|
47
50
|
});
|
@@ -22,7 +22,7 @@ const anthropicChatModels: AIChatModelCard[] = [
|
|
22
22
|
},
|
23
23
|
releasedAt: '2025-02-24',
|
24
24
|
settings: {
|
25
|
-
extendParams: ['enableReasoning', 'reasoningBudgetToken'],
|
25
|
+
extendParams: ['disableContextCaching', 'enableReasoning', 'reasoningBudgetToken'],
|
26
26
|
},
|
27
27
|
type: 'chat',
|
28
28
|
},
|
@@ -45,6 +45,9 @@ const anthropicChatModels: AIChatModelCard[] = [
|
|
45
45
|
writeCacheInput: 1.25,
|
46
46
|
},
|
47
47
|
releasedAt: '2024-11-05',
|
48
|
+
settings: {
|
49
|
+
extendParams: ['disableContextCaching'],
|
50
|
+
},
|
48
51
|
type: 'chat',
|
49
52
|
},
|
50
53
|
{
|
@@ -66,6 +69,9 @@ const anthropicChatModels: AIChatModelCard[] = [
|
|
66
69
|
writeCacheInput: 3.75,
|
67
70
|
},
|
68
71
|
releasedAt: '2024-10-22',
|
72
|
+
settings: {
|
73
|
+
extendParams: ['disableContextCaching'],
|
74
|
+
},
|
69
75
|
type: 'chat',
|
70
76
|
},
|
71
77
|
{
|
@@ -86,6 +92,9 @@ const anthropicChatModels: AIChatModelCard[] = [
|
|
86
92
|
writeCacheInput: 3.75,
|
87
93
|
},
|
88
94
|
releasedAt: '2024-06-20',
|
95
|
+
settings: {
|
96
|
+
extendParams: ['disableContextCaching'],
|
97
|
+
},
|
89
98
|
type: 'chat',
|
90
99
|
},
|
91
100
|
{
|
@@ -104,6 +113,9 @@ const anthropicChatModels: AIChatModelCard[] = [
|
|
104
113
|
output: 1.25,
|
105
114
|
},
|
106
115
|
releasedAt: '2024-03-07',
|
116
|
+
settings: {
|
117
|
+
extendParams: ['disableContextCaching'],
|
118
|
+
},
|
107
119
|
type: 'chat',
|
108
120
|
},
|
109
121
|
{
|
@@ -141,6 +153,9 @@ const anthropicChatModels: AIChatModelCard[] = [
|
|
141
153
|
output: 75,
|
142
154
|
},
|
143
155
|
releasedAt: '2024-02-29',
|
156
|
+
settings: {
|
157
|
+
extendParams: ['disableContextCaching'],
|
158
|
+
},
|
144
159
|
type: 'chat',
|
145
160
|
},
|
146
161
|
{
|
@@ -118,7 +118,6 @@ const googleChatModels: AIChatModelCard[] = [
|
|
118
118
|
description:
|
119
119
|
'Gemini 2.0 Flash Thinking Exp 是 Google 的实验性多模态推理AI模型,能对复杂问题进行推理,拥有新的思维能力。',
|
120
120
|
displayName: 'Gemini 2.0 Flash Thinking Experimental',
|
121
|
-
enabled: true,
|
122
121
|
id: 'gemini-2.0-flash-thinking-exp',
|
123
122
|
maxOutput: 65_536,
|
124
123
|
pricing: {
|
@@ -4,6 +4,20 @@ import { AIChatModelCard } from '@/types/aiModel';
|
|
4
4
|
// https://console.groq.com/docs/models
|
5
5
|
|
6
6
|
const groqChatModels: AIChatModelCard[] = [
|
7
|
+
{
|
8
|
+
abilities: {
|
9
|
+
functionCall: true,
|
10
|
+
reasoning: true,
|
11
|
+
},
|
12
|
+
contextWindowTokens: 131_072,
|
13
|
+
displayName: 'Qwen QwQ 32B',
|
14
|
+
id: 'qwen-qwq-32b',
|
15
|
+
pricing: {
|
16
|
+
input: 0.29,
|
17
|
+
output: 0.39,
|
18
|
+
},
|
19
|
+
type: 'chat',
|
20
|
+
},
|
7
21
|
{
|
8
22
|
abilities: {
|
9
23
|
functionCall: true,
|
@@ -150,6 +150,29 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
150
150
|
},
|
151
151
|
type: 'chat',
|
152
152
|
},
|
153
|
+
{
|
154
|
+
contextWindowTokens: 64_000,
|
155
|
+
displayName: 'Deepseek V3 Turbo',
|
156
|
+
id: 'deepseek/deepseek-v3-turbo',
|
157
|
+
pricing: {
|
158
|
+
input: 0.4,
|
159
|
+
output: 1.3,
|
160
|
+
},
|
161
|
+
type: 'chat',
|
162
|
+
},
|
163
|
+
{
|
164
|
+
abilities: {
|
165
|
+
reasoning: true,
|
166
|
+
},
|
167
|
+
contextWindowTokens: 64_000,
|
168
|
+
displayName: 'Deepseek R1 Turbo',
|
169
|
+
id: 'deepseek/deepseek-r1-turbo',
|
170
|
+
pricing: {
|
171
|
+
input: 0.7,
|
172
|
+
output: 2.5,
|
173
|
+
},
|
174
|
+
type: 'chat',
|
175
|
+
},
|
153
176
|
{
|
154
177
|
abilities: {
|
155
178
|
reasoning: true,
|
@@ -378,6 +401,19 @@ const novitaChatModels: AIChatModelCard[] = [
|
|
378
401
|
},
|
379
402
|
type: 'chat',
|
380
403
|
},
|
404
|
+
{
|
405
|
+
abilities: {
|
406
|
+
reasoning: true,
|
407
|
+
},
|
408
|
+
contextWindowTokens: 32_768,
|
409
|
+
displayName: 'QwQ 32B',
|
410
|
+
id: 'qwen/qwq-32b',
|
411
|
+
pricing: {
|
412
|
+
input: 0.18,
|
413
|
+
output: 0.2,
|
414
|
+
},
|
415
|
+
type: 'chat',
|
416
|
+
},
|
381
417
|
];
|
382
418
|
|
383
419
|
export const allModels = [...novitaChatModels];
|
@@ -226,9 +226,25 @@ const siliconcloudChatModels: AIChatModelCard[] = [
|
|
226
226
|
},
|
227
227
|
contextWindowTokens: 32_768,
|
228
228
|
description:
|
229
|
-
'QwQ-32B-
|
230
|
-
displayName: 'QwQ 32B
|
229
|
+
'QwQ 是 Qwen 系列的推理模型。与传统的指令调优模型相比,QwQ 具备思考和推理能力,能够在下游任务中实现显著增强的性能,尤其是在解决困难问题方面。QwQ-32B 是中型推理模型,能够在与最先进的推理模型(如 DeepSeek-R1、o1-mini)的对比中取得有竞争力的性能。该模型采用 RoPE、SwiGLU、RMSNorm 和 Attention QKV bias 等技术,具有 64 层网络结构和 40 个 Q 注意力头(GQA 架构中 KV 为 8 个)。',
|
230
|
+
displayName: 'QwQ 32B',
|
231
231
|
enabled: true,
|
232
|
+
id: 'Qwen/QwQ-32B',
|
233
|
+
pricing: {
|
234
|
+
currency: 'CNY',
|
235
|
+
input: 1,
|
236
|
+
output: 4,
|
237
|
+
},
|
238
|
+
type: 'chat',
|
239
|
+
},
|
240
|
+
{
|
241
|
+
abilities: {
|
242
|
+
reasoning: true,
|
243
|
+
},
|
244
|
+
contextWindowTokens: 32_768,
|
245
|
+
description:
|
246
|
+
'QwQ-32B-Preview 是 Qwen 最新的实验性研究模型,专注于提升AI推理能力。通过探索语言混合、递归推理等复杂机制,主要优势包括强大的推理分析能力、数学和编程能力。与此同时,也存在语言切换问题、推理循环、安全性考虑、其他能力方面的差异。',
|
247
|
+
displayName: 'QwQ 32B Preview',
|
232
248
|
id: 'Qwen/QwQ-32B-Preview',
|
233
249
|
pricing: {
|
234
250
|
currency: 'CNY',
|
@@ -180,12 +180,10 @@ const Anthropic: ModelProviderCard = {
|
|
180
180
|
sdkType: 'anthropic',
|
181
181
|
showModelFetcher: true,
|
182
182
|
smoothing: {
|
183
|
-
speed: 5,
|
184
183
|
text: true,
|
185
184
|
},
|
186
185
|
},
|
187
186
|
smoothing: {
|
188
|
-
speed: 5,
|
189
187
|
text: true,
|
190
188
|
},
|
191
189
|
url: 'https://anthropic.com',
|
@@ -20,7 +20,7 @@ export const FORM_STYLE: FormProps = {
|
|
20
20
|
style: { maxWidth: MAX_WIDTH, width: '100%' },
|
21
21
|
};
|
22
22
|
export const MOBILE_HEADER_ICON_SIZE = { blockSize: 36, fontSize: 22 };
|
23
|
-
export const DESKTOP_HEADER_ICON_SIZE = { fontSize:
|
23
|
+
export const DESKTOP_HEADER_ICON_SIZE = { blockSize: 32, fontSize: 20 };
|
24
24
|
export const HEADER_ICON_SIZE = (mobile?: boolean) =>
|
25
25
|
mobile ? MOBILE_HEADER_ICON_SIZE : DESKTOP_HEADER_ICON_SIZE;
|
26
26
|
export const PWA_INSTALL_ID = 'pwa-install';
|
@@ -0,0 +1,27 @@
|
|
1
|
+
export const systemToUserModels = new Set([
|
2
|
+
'o1-preview',
|
3
|
+
'o1-preview-2024-09-12',
|
4
|
+
'o1-mini',
|
5
|
+
'o1-mini-2024-09-12',
|
6
|
+
]);
|
7
|
+
|
8
|
+
// TODO: 临时写法,后续要重构成 model card 展示配置
|
9
|
+
export const disableStreamModels = new Set(['o1', 'o1-2024-12-17']);
|
10
|
+
|
11
|
+
/**
|
12
|
+
* models support context caching
|
13
|
+
*/
|
14
|
+
export const contextCachingModels = new Set([
|
15
|
+
'claude-3-7-sonnet-latest',
|
16
|
+
'claude-3-7-sonnet-20250219',
|
17
|
+
'claude-3-5-sonnet-latest',
|
18
|
+
'claude-3-5-sonnet-20241022',
|
19
|
+
'claude-3-5-sonnet-20240620',
|
20
|
+
'claude-3-5-haiku-latest',
|
21
|
+
'claude-3-5-haiku-20241022',
|
22
|
+
]);
|
23
|
+
|
24
|
+
export const thinkingWithToolClaudeModels = new Set([
|
25
|
+
'claude-3-7-sonnet-latest',
|
26
|
+
'claude-3-7-sonnet-20250219',
|
27
|
+
]);
|
@@ -7,15 +7,18 @@ import { Flexbox } from 'react-layout-kit';
|
|
7
7
|
|
8
8
|
import { useIsMobile } from '@/hooks/useIsMobile';
|
9
9
|
import { useAgentStore } from '@/store/agent';
|
10
|
-
import {
|
10
|
+
import { agentChatConfigSelectors } from '@/store/agent/selectors';
|
11
11
|
|
12
12
|
const History = memo(() => {
|
13
13
|
const { t } = useTranslation('setting');
|
14
14
|
const [popoverOpen, setPopoverOpen] = useState(false);
|
15
15
|
|
16
16
|
const [historyCount, enableHistoryCount, updateAgentConfig] = useAgentStore((s) => {
|
17
|
-
|
18
|
-
|
17
|
+
return [
|
18
|
+
agentChatConfigSelectors.historyCount(s),
|
19
|
+
agentChatConfigSelectors.enableHistoryCount(s),
|
20
|
+
s.updateAgentChatConfig,
|
21
|
+
];
|
19
22
|
});
|
20
23
|
|
21
24
|
const title = t(
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import { Switch } from 'antd';
|
2
|
+
import { memo } from 'react';
|
3
|
+
|
4
|
+
interface ContextCachingSwitchProps {
|
5
|
+
onChange?: (value: boolean) => void;
|
6
|
+
value?: boolean;
|
7
|
+
}
|
8
|
+
|
9
|
+
const ContextCachingSwitch = memo<ContextCachingSwitchProps>(({ value, onChange }) => {
|
10
|
+
return (
|
11
|
+
<Switch
|
12
|
+
onChange={(checked) => {
|
13
|
+
onChange?.(!checked);
|
14
|
+
}}
|
15
|
+
value={!value}
|
16
|
+
/>
|
17
|
+
);
|
18
|
+
});
|
19
|
+
|
20
|
+
export default ContextCachingSwitch;
|
@@ -1,14 +1,16 @@
|
|
1
1
|
import { Form } from '@lobehub/ui';
|
2
2
|
import type { FormItemProps } from '@lobehub/ui';
|
3
|
-
import { Switch } from 'antd';
|
3
|
+
import { Form as AntdForm, Switch } from 'antd';
|
4
4
|
import isEqual from 'fast-deep-equal';
|
5
|
+
import Link from 'next/link';
|
5
6
|
import { memo } from 'react';
|
6
|
-
import { useTranslation } from 'react-i18next';
|
7
|
+
import { Trans, useTranslation } from 'react-i18next';
|
7
8
|
|
8
9
|
import { useAgentStore } from '@/store/agent';
|
9
|
-
import { agentSelectors } from '@/store/agent/
|
10
|
+
import { agentChatConfigSelectors, agentSelectors } from '@/store/agent/selectors';
|
10
11
|
import { aiModelSelectors, useAiInfraStore } from '@/store/aiInfra';
|
11
12
|
|
13
|
+
import ContextCachingSwitch from './ContextCachingSwitch';
|
12
14
|
import ReasoningTokenSlider from './ReasoningTokenSlider';
|
13
15
|
|
14
16
|
const ControlsForm = memo(() => {
|
@@ -18,18 +20,57 @@ const ControlsForm = memo(() => {
|
|
18
20
|
agentSelectors.currentAgentModelProvider(s),
|
19
21
|
s.updateAgentChatConfig,
|
20
22
|
]);
|
21
|
-
const
|
23
|
+
const [form] = Form.useForm();
|
24
|
+
const enableReasoning = AntdForm.useWatch(['enableReasoning'], form);
|
25
|
+
|
26
|
+
const config = useAgentStore(agentChatConfigSelectors.currentChatConfig, isEqual);
|
22
27
|
|
23
28
|
const modelExtendParams = useAiInfraStore(aiModelSelectors.modelExtendParams(model, provider));
|
24
29
|
|
25
|
-
const items
|
30
|
+
const items = [
|
31
|
+
{
|
32
|
+
children: <ContextCachingSwitch />,
|
33
|
+
desc: (
|
34
|
+
<span style={{ display: 'inline-block', width: 300 }}>
|
35
|
+
<Trans i18nKey={'extendParams.disableContextCaching.desc'} ns={'chat'}>
|
36
|
+
单条对话生成成本最高可降低 90%,响应速度提升 4 倍(
|
37
|
+
<Link
|
38
|
+
href={'https://www.anthropic.com/news/prompt-caching?utm_source=lobechat'}
|
39
|
+
rel={'nofollow'}
|
40
|
+
>
|
41
|
+
了解更多
|
42
|
+
</Link>
|
43
|
+
)。开启后将自动禁用历史记录限制
|
44
|
+
</Trans>
|
45
|
+
</span>
|
46
|
+
),
|
47
|
+
label: t('extendParams.disableContextCaching.title'),
|
48
|
+
minWidth: undefined,
|
49
|
+
name: 'disableContextCaching',
|
50
|
+
},
|
26
51
|
{
|
27
52
|
children: <Switch />,
|
53
|
+
desc: (
|
54
|
+
<span style={{ display: 'inline-block', width: 300 }}>
|
55
|
+
<Trans i18nKey={'extendParams.enableReasoning.desc'} ns={'chat'}>
|
56
|
+
基于 Claude Thinking 机制限制(
|
57
|
+
<Link
|
58
|
+
href={
|
59
|
+
'https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking?utm_source=lobechat#why-thinking-blocks-must-be-preserved'
|
60
|
+
}
|
61
|
+
rel={'nofollow'}
|
62
|
+
>
|
63
|
+
了解更多
|
64
|
+
</Link>
|
65
|
+
),开启后将自动禁用历史消息数限制
|
66
|
+
</Trans>
|
67
|
+
</span>
|
68
|
+
),
|
28
69
|
label: t('extendParams.enableReasoning.title'),
|
29
70
|
minWidth: undefined,
|
30
71
|
name: 'enableReasoning',
|
31
72
|
},
|
32
|
-
{
|
73
|
+
enableReasoning && {
|
33
74
|
children: <ReasoningTokenSlider />,
|
34
75
|
label: t('extendParams.reasoningBudgetToken.title'),
|
35
76
|
layout: 'vertical',
|
@@ -39,10 +80,11 @@ const ControlsForm = memo(() => {
|
|
39
80
|
paddingBottom: 0,
|
40
81
|
},
|
41
82
|
},
|
42
|
-
];
|
83
|
+
].filter(Boolean) as FormItemProps[];
|
43
84
|
|
44
85
|
return (
|
45
86
|
<Form
|
87
|
+
form={form}
|
46
88
|
initialValues={config}
|
47
89
|
items={
|
48
90
|
(modelExtendParams || [])
|