@lobehub/chat 1.135.3 → 1.135.4
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 +33 -0
- package/changelog/v1.json +9 -0
- package/package.json +2 -2
- package/packages/const/src/index.ts +1 -0
- package/packages/const/src/settings/index.ts +1 -0
- package/packages/model-bank/src/aiModels/aihubmix.ts +25 -0
- package/packages/model-bank/src/aiModels/nvidia.ts +17 -1
- package/packages/model-bank/src/aiModels/openai.ts +80 -1
- package/packages/model-runtime/src/const/models.ts +2 -0
- package/packages/model-runtime/src/providers/openai/index.ts +15 -11
- package/packages/model-runtime/src/providers/openrouter/index.ts +7 -2
- package/packages/model-runtime/src/providers/openrouter/type.ts +4 -2
- package/packages/model-runtime/src/providers/vercelaigateway/index.ts +7 -0
- package/packages/model-runtime/src/utils/modelParse.ts +31 -3
- package/packages/types/src/aiProvider.ts +1 -2
- package/packages/types/src/discover/models.ts +3 -2
- package/packages/types/src/discover/providers.ts +3 -2
- package/packages/types/src/message/chat.ts +13 -0
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/index.tsx +1 -5
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/WelcomeMessage.tsx +1 -1
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/CreateNewModelModal/Form.tsx +1 -2
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/ModelItem.tsx +1 -4
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/SortModelModal/ListItem.tsx +1 -2
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/SortModelModal/index.tsx +1 -1
- package/src/{components → features}/ChatItem/ChatItem.tsx +5 -35
- package/src/{components → features}/ChatItem/components/MessageContent.tsx +27 -7
- package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeArtifact/Render/index.tsx +1 -1
- package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/getNodeContent.test.ts +1 -1
- package/src/features/Conversation/{Actions → Messages/Assistant/Actions}/Error.tsx +1 -1
- package/src/features/Conversation/{components/ChatItem/ActionsBar.tsx → Messages/Assistant/Actions/index.tsx} +71 -44
- package/src/features/Conversation/Messages/Assistant/Block.tsx +63 -0
- package/src/features/Conversation/{Extras/Assistant.test.tsx → Messages/Assistant/Extra/index.test.tsx} +36 -31
- package/src/features/Conversation/{Extras/Assistant.tsx → Messages/Assistant/Extra/index.tsx} +13 -7
- package/src/features/Conversation/Messages/Assistant/MessageContent.tsx +102 -0
- package/src/features/Conversation/Messages/Assistant/index.tsx +235 -84
- package/src/features/Conversation/Messages/User/Actions.tsx +153 -0
- package/src/features/Conversation/Messages/User/BelowMessage.tsx +7 -2
- package/src/features/Conversation/{Extras/User.tsx → Messages/User/Extra.tsx} +9 -7
- package/src/features/Conversation/Messages/User/MessageContent.tsx +31 -0
- package/src/features/Conversation/Messages/User/index.tsx +127 -24
- package/src/features/Conversation/Messages/index.tsx +152 -0
- package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/ModelCard.tsx +4 -3
- package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/pricing.ts +3 -2
- package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/tokens.test.ts +2 -3
- package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareImage/Preview.tsx +1 -1
- package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareText/index.tsx +1 -1
- package/src/features/Conversation/components/VirtualizedList/index.tsx +1 -0
- package/src/features/Conversation/hooks/useChatListActionsBar.tsx +29 -1
- package/src/features/Conversation/hooks/useDoubleClickEdit.ts +42 -0
- package/src/features/Conversation/index.ts +1 -1
- package/src/features/Conversation/types/{index.tsx → index.ts} +0 -7
- package/src/features/Portal/Thread/Chat/ChatItem.tsx +0 -7
- package/src/hooks/useUserAvatar.test.ts +129 -0
- package/src/hooks/useUserAvatar.ts +19 -0
- package/src/server/routers/lambda/aiModel.ts +7 -8
- package/src/store/user/slices/settings/selectors/settings.ts +6 -5
- package/src/features/ChatItem/index.tsx +0 -58
- package/src/features/Conversation/Actions/Assistant.tsx +0 -68
- package/src/features/Conversation/Actions/Fallback.tsx +0 -19
- package/src/features/Conversation/Actions/Tool.tsx +0 -33
- package/src/features/Conversation/Actions/User.tsx +0 -39
- package/src/features/Conversation/Actions/customAction.ts +0 -37
- package/src/features/Conversation/Actions/index.ts +0 -14
- package/src/features/Conversation/Extras/index.ts +0 -8
- package/src/features/Conversation/Extras/type.ts +0 -5
- package/src/features/Conversation/Messages/index.ts +0 -45
- package/src/features/Conversation/components/ChatItem/index.tsx +0 -358
- /package/src/{components → features}/ChatItem/components/Actions.tsx +0 -0
- /package/src/{components → features}/ChatItem/components/Avatar.tsx +0 -0
- /package/src/{components → features}/ChatItem/components/BorderSpacing.tsx +0 -0
- /package/src/{components → features}/ChatItem/components/ErrorContent.tsx +0 -0
- /package/src/{components → features}/ChatItem/components/Loading.tsx +0 -0
- /package/src/{components → features}/ChatItem/components/Title.tsx +0 -0
- /package/src/{components → features}/ChatItem/index.ts +0 -0
- /package/src/{components → features}/ChatItem/style.ts +0 -0
- /package/src/{components → features}/ChatItem/type.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeArtifact/Render/Icon.tsx +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeArtifact/index.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeArtifact/rehypePlugin.test.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeArtifact/rehypePlugin.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeThinking/Render.tsx +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeThinking/index.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LocalFile/Render/index.tsx +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LocalFile/index.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/Thinking/Render.tsx +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/Thinking/index.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/index.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/__snapshots__/createRemarkSelfClosingTagPlugin.test.ts.snap +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/createRemarkCustomTagPlugin.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/createRemarkSelfClosingTagPlugin.test.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/createRemarkSelfClosingTagPlugin.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/getNodeContent.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/type.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/utils.ts +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/ExtraContainer.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/TTS/FilePlayer.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/TTS/InitPlayer.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/TTS/Player.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/TTS/index.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/Translate.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/TokenProgress.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/index.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/tokens.ts +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/Usage/index.tsx +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareImage/index.tsx +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareImage/style.ts +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareImage/type.ts +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareText/Preview.tsx +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareText/template.test.ts +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareText/template.ts +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareText/type.ts +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/index.tsx +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/style.ts +0 -0
- /package/src/features/Conversation/{components/ChatItem → context}/InPortalThreadContext.ts +0 -0
- /package/src/features/Conversation/{components/ChatItem/utils.test.ts → utils.test.ts} +0 -0
- /package/src/features/Conversation/{components/ChatItem/utils.ts → utils.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
### [Version 1.135.4](https://github.com/lobehub/lobe-chat/compare/v1.135.3...v1.135.4)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2025-10-07**</sup>
|
|
8
|
+
|
|
9
|
+
#### ♻ Code Refactoring
|
|
10
|
+
|
|
11
|
+
- **misc**: Refactor chat item.
|
|
12
|
+
|
|
13
|
+
#### 💄 Styles
|
|
14
|
+
|
|
15
|
+
- **misc**: Add GPT-5 pro model.
|
|
16
|
+
|
|
17
|
+
<br/>
|
|
18
|
+
|
|
19
|
+
<details>
|
|
20
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
21
|
+
|
|
22
|
+
#### Code refactoring
|
|
23
|
+
|
|
24
|
+
- **misc**: Refactor chat item, closes [#9599](https://github.com/lobehub/lobe-chat/issues/9599) ([1f36158](https://github.com/lobehub/lobe-chat/commit/1f36158))
|
|
25
|
+
|
|
26
|
+
#### Styles
|
|
27
|
+
|
|
28
|
+
- **misc**: Add GPT-5 pro model, closes [#9594](https://github.com/lobehub/lobe-chat/issues/9594) ([775f30b](https://github.com/lobehub/lobe-chat/commit/775f30b))
|
|
29
|
+
|
|
30
|
+
</details>
|
|
31
|
+
|
|
32
|
+
<div align="right">
|
|
33
|
+
|
|
34
|
+
[](#readme-top)
|
|
35
|
+
|
|
36
|
+
</div>
|
|
37
|
+
|
|
5
38
|
### [Version 1.135.3](https://github.com/lobehub/lobe-chat/compare/v1.135.2...v1.135.3)
|
|
6
39
|
|
|
7
40
|
<sup>Released on **2025-10-07**</sup>
|
package/changelog/v1.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "1.135.
|
|
3
|
+
"version": "1.135.4",
|
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -301,7 +301,7 @@
|
|
|
301
301
|
"@peculiar/webcrypto": "^1.5.0",
|
|
302
302
|
"@prettier/sync": "^0.6.1",
|
|
303
303
|
"@semantic-release/exec": "^6.0.3",
|
|
304
|
-
"@testing-library/jest-dom": "
|
|
304
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
305
305
|
"@testing-library/react": "^16.3.0",
|
|
306
306
|
"@testing-library/user-event": "^14.6.1",
|
|
307
307
|
"@types/chroma-js": "^3.1.1",
|
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
import { AIChatModelCard } from '../types/aiModel';
|
|
2
2
|
|
|
3
3
|
const aihubmixModels: AIChatModelCard[] = [
|
|
4
|
+
{
|
|
5
|
+
abilities: {
|
|
6
|
+
functionCall: true,
|
|
7
|
+
reasoning: true,
|
|
8
|
+
search: true,
|
|
9
|
+
vision: true,
|
|
10
|
+
},
|
|
11
|
+
contextWindowTokens: 400_000,
|
|
12
|
+
description: 'GPT-5 pro 使用更多计算来更深入地思考,并持续提供更好的答案。',
|
|
13
|
+
displayName: 'GPT-5 pro',
|
|
14
|
+
id: 'gpt-5-pro',
|
|
15
|
+
maxOutput: 272_000,
|
|
16
|
+
pricing: {
|
|
17
|
+
units: [
|
|
18
|
+
{ name: 'textInput', rate: 15, strategy: 'fixed', unit: 'millionTokens' },
|
|
19
|
+
{ name: 'textOutput', rate: 120, strategy: 'fixed', unit: 'millionTokens' },
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
releasedAt: '2025-10-06',
|
|
23
|
+
settings: {
|
|
24
|
+
extendParams: ['textVerbosity'],
|
|
25
|
+
searchImpl: 'params',
|
|
26
|
+
},
|
|
27
|
+
type: 'chat',
|
|
28
|
+
},
|
|
4
29
|
{
|
|
5
30
|
abilities: {
|
|
6
31
|
functionCall: true,
|
|
@@ -9,8 +9,24 @@ const nvidiaChatModels: AIChatModelCard[] = [
|
|
|
9
9
|
contextWindowTokens: 131_072,
|
|
10
10
|
description:
|
|
11
11
|
'DeepSeek V3.1:下一代推理模型,提升了复杂推理与链路思考能力,适合需要深入分析的任务。',
|
|
12
|
-
displayName: 'DeepSeek V3.1',
|
|
12
|
+
displayName: 'DeepSeek V3.1 Terminus',
|
|
13
13
|
enabled: true,
|
|
14
|
+
id: 'deepseek-ai/deepseek-v3.1-terminus',
|
|
15
|
+
maxOutput: 16_384,
|
|
16
|
+
settings: {
|
|
17
|
+
extendParams: ['enableReasoning'],
|
|
18
|
+
},
|
|
19
|
+
type: 'chat',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
abilities: {
|
|
23
|
+
functionCall: true,
|
|
24
|
+
reasoning: true,
|
|
25
|
+
},
|
|
26
|
+
contextWindowTokens: 131_072,
|
|
27
|
+
description:
|
|
28
|
+
'DeepSeek V3.1:下一代推理模型,提升了复杂推理与链路思考能力,适合需要深入分析的任务。',
|
|
29
|
+
displayName: 'DeepSeek V3.1',
|
|
14
30
|
id: 'deepseek-ai/deepseek-v3.1',
|
|
15
31
|
maxOutput: 16_384,
|
|
16
32
|
settings: {
|
|
@@ -18,6 +18,31 @@ export const gptImage1ParamsSchema: ModelParamsSchema = {
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
export const openaiChatModels: AIChatModelCard[] = [
|
|
21
|
+
{
|
|
22
|
+
abilities: {
|
|
23
|
+
functionCall: true,
|
|
24
|
+
reasoning: true,
|
|
25
|
+
search: true,
|
|
26
|
+
vision: true,
|
|
27
|
+
},
|
|
28
|
+
contextWindowTokens: 400_000,
|
|
29
|
+
description: 'GPT-5 pro 使用更多计算来更深入地思考,并持续提供更好的答案。',
|
|
30
|
+
displayName: 'GPT-5 pro',
|
|
31
|
+
id: 'gpt-5-pro',
|
|
32
|
+
maxOutput: 272_000,
|
|
33
|
+
pricing: {
|
|
34
|
+
units: [
|
|
35
|
+
{ name: 'textInput', rate: 15, strategy: 'fixed', unit: 'millionTokens' },
|
|
36
|
+
{ name: 'textOutput', rate: 120, strategy: 'fixed', unit: 'millionTokens' },
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
releasedAt: '2025-10-06',
|
|
40
|
+
settings: {
|
|
41
|
+
extendParams: ['textVerbosity'],
|
|
42
|
+
searchImpl: 'params',
|
|
43
|
+
},
|
|
44
|
+
type: 'chat',
|
|
45
|
+
},
|
|
21
46
|
{
|
|
22
47
|
abilities: {
|
|
23
48
|
functionCall: true,
|
|
@@ -614,7 +639,7 @@ export const openaiChatModels: AIChatModelCard[] = [
|
|
|
614
639
|
contextWindowTokens: 128_000,
|
|
615
640
|
description: 'GPT-4o Audio Preview 模型,支持音频输入输出',
|
|
616
641
|
displayName: 'GPT-4o Audio Preview',
|
|
617
|
-
id: 'gpt-4o-audio-preview',
|
|
642
|
+
id: 'gpt-4o-audio-preview',
|
|
618
643
|
maxOutput: 16_384,
|
|
619
644
|
pricing: {
|
|
620
645
|
units: [
|
|
@@ -1046,9 +1071,63 @@ export const openaiImageModels: AIImageModelCard[] = [
|
|
|
1046
1071
|
{ name: 'imageInput', rate: 10, strategy: 'fixed', unit: 'millionTokens' },
|
|
1047
1072
|
{ name: 'imageInput_cacheRead', rate: 2.5, strategy: 'fixed', unit: 'millionTokens' },
|
|
1048
1073
|
{ name: 'imageOutput', rate: 40, strategy: 'fixed', unit: 'millionTokens' },
|
|
1074
|
+
{
|
|
1075
|
+
lookup: {
|
|
1076
|
+
prices: {
|
|
1077
|
+
'low_1024x1024': 0.011,
|
|
1078
|
+
'low_1024x1536': 0.016,
|
|
1079
|
+
'low_1536x1024': 0.016,
|
|
1080
|
+
'medium_1024x1024': 0.042,
|
|
1081
|
+
'medium_1024x1536': 0.063,
|
|
1082
|
+
'medium_1536x1024': 0.063,
|
|
1083
|
+
'high_1024x1024': 0.167,
|
|
1084
|
+
'high_1024x1536': 0.25,
|
|
1085
|
+
'high_1536x1024': 0.25,
|
|
1086
|
+
},
|
|
1087
|
+
pricingParams: ['quality', 'size'],
|
|
1088
|
+
},
|
|
1089
|
+
name: 'imageGeneration',
|
|
1090
|
+
strategy: 'lookup',
|
|
1091
|
+
unit: 'image',
|
|
1092
|
+
},
|
|
1093
|
+
],
|
|
1094
|
+
},
|
|
1095
|
+
resolutions: ['1024x1024', '1024x1536', '1536x1024'],
|
|
1096
|
+
type: 'image',
|
|
1097
|
+
},
|
|
1098
|
+
{
|
|
1099
|
+
description: '成本更低的 GPT Image 1 版本,原生支持文本与图像输入并生成图像输出。',
|
|
1100
|
+
displayName: 'GPT Image 1 Mini',
|
|
1101
|
+
enabled: true,
|
|
1102
|
+
id: 'gpt-image-1-mini',
|
|
1103
|
+
parameters: gptImage1ParamsSchema,
|
|
1104
|
+
pricing: {
|
|
1105
|
+
units: [
|
|
1106
|
+
{ name: 'textInput', rate: 2, strategy: 'fixed', unit: 'millionTokens' },
|
|
1107
|
+
{ name: 'textInput_cacheRead', rate: 0.2, strategy: 'fixed', unit: 'millionTokens' },
|
|
1108
|
+
{ name: 'imageInput', rate: 2.5, strategy: 'fixed', unit: 'millionTokens' },
|
|
1109
|
+
{ name: 'imageInput_cacheRead', rate: 0.25, strategy: 'fixed', unit: 'millionTokens' },
|
|
1110
|
+
{ name: 'imageOutput', rate: 8, strategy: 'fixed', unit: 'millionTokens' },
|
|
1111
|
+
{
|
|
1112
|
+
lookup: {
|
|
1113
|
+
prices: {
|
|
1114
|
+
'low_1024x1024': 0.005,
|
|
1115
|
+
'low_1024x1536': 0.006,
|
|
1116
|
+
'low_1536x1024': 0.006,
|
|
1117
|
+
'medium_1024x1024': 0.011,
|
|
1118
|
+
'medium_1024x1536': 0.015,
|
|
1119
|
+
'medium_1536x1024': 0.015,
|
|
1120
|
+
},
|
|
1121
|
+
pricingParams: ['quality', 'size'],
|
|
1122
|
+
},
|
|
1123
|
+
name: 'imageGeneration',
|
|
1124
|
+
strategy: 'lookup',
|
|
1125
|
+
unit: 'image',
|
|
1126
|
+
},
|
|
1049
1127
|
],
|
|
1050
1128
|
},
|
|
1051
1129
|
resolutions: ['1024x1024', '1024x1536', '1536x1024'],
|
|
1130
|
+
releasedAt: '2025-10-06',
|
|
1052
1131
|
type: 'image',
|
|
1053
1132
|
},
|
|
1054
1133
|
{
|
|
@@ -81,23 +81,27 @@ export const LobeOpenAI = createOpenAICompatibleRuntime({
|
|
|
81
81
|
|
|
82
82
|
const openaiTools = enabledSearch
|
|
83
83
|
? [
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
...(tools || []),
|
|
85
|
+
{
|
|
86
|
+
type: 'web_search',
|
|
87
|
+
...(oaiSearchContextSize && {
|
|
88
|
+
search_context_size: oaiSearchContextSize,
|
|
89
|
+
}),
|
|
90
|
+
},
|
|
91
|
+
]
|
|
92
92
|
: tools;
|
|
93
93
|
|
|
94
94
|
if (prunePrefixes.some((prefix) => model.startsWith(prefix))) {
|
|
95
|
+
const reasoning = payload.reasoning
|
|
96
|
+
? { ...payload.reasoning, summary: 'auto' }
|
|
97
|
+
: { summary: 'auto' };
|
|
98
|
+
if (model.startsWith('gpt-5-pro')) {
|
|
99
|
+
reasoning.effort = 'high';
|
|
100
|
+
}
|
|
95
101
|
return pruneReasoningPayload({
|
|
96
102
|
...rest,
|
|
97
103
|
model,
|
|
98
|
-
reasoning
|
|
99
|
-
? { ...payload.reasoning, summary: 'auto' }
|
|
100
|
-
: { summary: 'auto' },
|
|
104
|
+
reasoning,
|
|
101
105
|
...(enableServiceTierFlex && supportsFlexTier(model) && { service_tier: 'flex' }),
|
|
102
106
|
stream: payload.stream ?? true,
|
|
103
107
|
tools: openaiTools as any,
|
|
@@ -4,8 +4,8 @@ import { createOpenAICompatibleRuntime } from '../../core/openaiCompatibleFactor
|
|
|
4
4
|
import { processMultiProviderModelList } from '../../utils/modelParse';
|
|
5
5
|
import { OpenRouterModelCard, OpenRouterReasoning } from './type';
|
|
6
6
|
|
|
7
|
-
const formatPrice = (price
|
|
8
|
-
if (price === '-1') return undefined;
|
|
7
|
+
const formatPrice = (price?: string) => {
|
|
8
|
+
if (price === undefined || price === '-1') return undefined;
|
|
9
9
|
return Number((Number(price) * 1e6).toPrecision(5));
|
|
10
10
|
};
|
|
11
11
|
|
|
@@ -81,6 +81,9 @@ export const LobeOpenRouterAI = createOpenAICompatibleRuntime({
|
|
|
81
81
|
|
|
82
82
|
const inputPrice = formatPrice(endpoint?.pricing?.prompt);
|
|
83
83
|
const outputPrice = formatPrice(endpoint?.pricing?.completion);
|
|
84
|
+
const cachedInputPrice = formatPrice(endpoint?.pricing?.input_cache_read);
|
|
85
|
+
const writeCacheInputPrice = formatPrice(endpoint?.pricing?.input_cache_write);
|
|
86
|
+
|
|
84
87
|
const isFree = (inputPrice === 0 || outputPrice === 0) && !displayName.endsWith('(free)');
|
|
85
88
|
if (isFree) {
|
|
86
89
|
displayName += ' (free)';
|
|
@@ -98,6 +101,8 @@ export const LobeOpenRouterAI = createOpenAICompatibleRuntime({
|
|
|
98
101
|
: undefined,
|
|
99
102
|
pricing: {
|
|
100
103
|
input: inputPrice,
|
|
104
|
+
cachedInput: cachedInputPrice,
|
|
105
|
+
writeCacheInput: writeCacheInputPrice,
|
|
101
106
|
output: outputPrice,
|
|
102
107
|
},
|
|
103
108
|
reasoning: endpoint?.supports_reasoning || false,
|
|
@@ -13,6 +13,8 @@ export interface VercelAIGatewayModelCard {
|
|
|
13
13
|
pricing?: {
|
|
14
14
|
input?: string | number;
|
|
15
15
|
output?: string | number;
|
|
16
|
+
input_cache_read?: string | number;
|
|
17
|
+
input_cache_write?: string | number;
|
|
16
18
|
};
|
|
17
19
|
tags?: string[];
|
|
18
20
|
type?: string;
|
|
@@ -68,6 +70,9 @@ export const LobeVercelAIGatewayAI = createOpenAICompatibleRuntime({
|
|
|
68
70
|
|
|
69
71
|
const inputPrice = formatPrice(m.pricing?.input);
|
|
70
72
|
const outputPrice = formatPrice(m.pricing?.output);
|
|
73
|
+
const cachedInputPrice = formatPrice(m.pricing?.input_cache_read);
|
|
74
|
+
const writeCacheInputPrice = formatPrice(m.pricing?.input_cache_write);
|
|
75
|
+
|
|
71
76
|
let displayName = m.name ?? m.id;
|
|
72
77
|
if (inputPrice === 0 && outputPrice === 0) {
|
|
73
78
|
displayName += ' (free)';
|
|
@@ -82,8 +87,10 @@ export const LobeVercelAIGatewayAI = createOpenAICompatibleRuntime({
|
|
|
82
87
|
id: m.id,
|
|
83
88
|
maxOutput: typeof m.max_tokens === 'number' ? m.max_tokens : undefined,
|
|
84
89
|
pricing: {
|
|
90
|
+
cachedInput: cachedInputPrice,
|
|
85
91
|
input: inputPrice,
|
|
86
92
|
output: outputPrice,
|
|
93
|
+
writeCacheInput: writeCacheInputPrice,
|
|
87
94
|
},
|
|
88
95
|
reasoning: tags.includes('reasoning') || false,
|
|
89
96
|
type: m.type === 'embedding' ? 'embedding' : 'chat',
|
|
@@ -326,13 +326,25 @@ const processModelCard = (
|
|
|
326
326
|
return undefined;
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
-
const formatPricing = (pricing?: {
|
|
329
|
+
const formatPricing = (pricing?: {
|
|
330
|
+
cachedInput?: number;
|
|
331
|
+
input?: number;
|
|
332
|
+
output?: number;
|
|
333
|
+
units?: any[];
|
|
334
|
+
writeCacheInput?: number;
|
|
335
|
+
}) => {
|
|
330
336
|
if (!pricing || typeof pricing !== 'object') return undefined;
|
|
331
337
|
if (Array.isArray(pricing.units)) {
|
|
332
338
|
return { units: pricing.units };
|
|
333
339
|
}
|
|
334
|
-
const { input, output } = pricing;
|
|
335
|
-
if (
|
|
340
|
+
const { input, output, cachedInput, writeCacheInput } = pricing;
|
|
341
|
+
if (
|
|
342
|
+
typeof input !== 'number' &&
|
|
343
|
+
typeof output !== 'number' &&
|
|
344
|
+
typeof cachedInput !== 'number' &&
|
|
345
|
+
typeof writeCacheInput !== 'number'
|
|
346
|
+
)
|
|
347
|
+
return undefined;
|
|
336
348
|
|
|
337
349
|
const units = [];
|
|
338
350
|
if (typeof input === 'number') {
|
|
@@ -351,6 +363,22 @@ const processModelCard = (
|
|
|
351
363
|
unit: 'millionTokens' as const,
|
|
352
364
|
});
|
|
353
365
|
}
|
|
366
|
+
if (typeof cachedInput === 'number') {
|
|
367
|
+
units.push({
|
|
368
|
+
name: 'textInput_cacheRead' as const,
|
|
369
|
+
rate: cachedInput,
|
|
370
|
+
strategy: 'fixed' as const,
|
|
371
|
+
unit: 'millionTokens' as const,
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
if (typeof writeCacheInput === 'number') {
|
|
375
|
+
units.push({
|
|
376
|
+
name: 'textInput_cacheWrite' as const,
|
|
377
|
+
rate: writeCacheInput,
|
|
378
|
+
strategy: 'fixed' as const,
|
|
379
|
+
unit: 'millionTokens' as const,
|
|
380
|
+
});
|
|
381
|
+
}
|
|
354
382
|
return { units };
|
|
355
383
|
};
|
|
356
384
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
+
import { AiModelForSelect, EnabledAiModel, ModelSearchImplementType } from 'model-bank';
|
|
1
2
|
import { z } from 'zod';
|
|
2
3
|
|
|
3
|
-
import { AiModelForSelect, EnabledAiModel, ModelSearchImplementType } from '../../model-bank/src/types/aiModel';
|
|
4
|
-
|
|
5
4
|
export type ResponseAnimationStyle = 'smooth' | 'fadeIn' | 'none';
|
|
6
5
|
export type ResponseAnimation =
|
|
7
6
|
| {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { LobeDefaultAiModelListItem } from '
|
|
2
|
-
|
|
1
|
+
import { LobeDefaultAiModelListItem } from 'model-bank';
|
|
2
|
+
|
|
3
|
+
import { ModelProviderCard } from '../llm';
|
|
3
4
|
|
|
4
5
|
export enum ModelSorts {
|
|
5
6
|
ContextWindowTokens = 'contextWindowTokens',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { LobeDefaultAiModelListItem } from '
|
|
2
|
-
|
|
1
|
+
import { LobeDefaultAiModelListItem } from 'model-bank';
|
|
2
|
+
|
|
3
|
+
import { ModelProviderCard } from '../llm';
|
|
3
4
|
|
|
4
5
|
export enum ProviderSorts {
|
|
5
6
|
Default = 'default',
|
|
@@ -46,9 +46,22 @@ export interface ChatMessageExtra {
|
|
|
46
46
|
tts?: ChatTTS;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
export interface AssistantContentBlock {
|
|
50
|
+
content: string;
|
|
51
|
+
fileList?: ChatFileItem[];
|
|
52
|
+
id: string;
|
|
53
|
+
imageList?: ChatImageItem[];
|
|
54
|
+
tools?: ChatToolPayload[];
|
|
55
|
+
}
|
|
56
|
+
|
|
49
57
|
export interface ChatMessage {
|
|
50
58
|
// Group chat fields (alphabetically before other fields)
|
|
51
59
|
agentId?: string | 'supervisor';
|
|
60
|
+
/**
|
|
61
|
+
* children messages for grouped display
|
|
62
|
+
* Used to group tool messages under their parent assistant message
|
|
63
|
+
*/
|
|
64
|
+
children?: AssistantContentBlock[];
|
|
52
65
|
chunksList?: ChatFileChunk[];
|
|
53
66
|
content: string;
|
|
54
67
|
createdAt: number;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { createStyles } from 'antd-style';
|
|
2
|
-
import React, { memo
|
|
2
|
+
import React, { memo } from 'react';
|
|
3
3
|
|
|
4
4
|
import { ChatItem } from '@/features/Conversation';
|
|
5
|
-
import ActionsBar from '@/features/Conversation/components/ChatItem/ActionsBar';
|
|
6
5
|
import { useAgentStore } from '@/store/agent';
|
|
7
6
|
import { agentChatConfigSelectors } from '@/store/agent/selectors';
|
|
8
7
|
import { useChatStore } from '@/store/chat';
|
|
@@ -64,11 +63,8 @@ const MainChatItem = memo<ThreadChatItemProps>(({ id, index }) => {
|
|
|
64
63
|
|
|
65
64
|
const placement = displayMode === 'chat' && userRole === 'user' ? 'end' : 'start';
|
|
66
65
|
|
|
67
|
-
const actionBar = useMemo(() => <ActionsBar id={id} index={index} />, [id]);
|
|
68
|
-
|
|
69
66
|
return (
|
|
70
67
|
<ChatItem
|
|
71
|
-
actionBar={actionBar}
|
|
72
68
|
className={showThread ? cx(styles.line, styles[placement]) : ''}
|
|
73
69
|
enableHistoryDivider={enableHistoryDivider}
|
|
74
70
|
endRender={
|
|
@@ -4,7 +4,7 @@ import React, { useMemo } from 'react';
|
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { Flexbox } from 'react-layout-kit';
|
|
6
6
|
|
|
7
|
-
import ChatItem from '@/features/ChatItem';
|
|
7
|
+
import { ChatItem } from '@/features/ChatItem';
|
|
8
8
|
import { useAgentStore } from '@/store/agent';
|
|
9
9
|
import { agentChatConfigSelectors, agentSelectors } from '@/store/agent/selectors';
|
|
10
10
|
import { useChatStore } from '@/store/chat';
|
package/src/app/[variants]/(main)/settings/provider/features/ModelList/CreateNewModelModal/Form.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Input } from '@lobehub/ui';
|
|
2
2
|
import { Checkbox, Form, FormInstance, Select } from 'antd';
|
|
3
|
+
import { AiModelType } from 'model-bank';
|
|
3
4
|
import { memo, useEffect, useMemo } from 'react';
|
|
4
5
|
import { useTranslation } from 'react-i18next';
|
|
5
6
|
|
|
@@ -7,8 +8,6 @@ import MaxTokenSlider from '@/components/MaxTokenSlider';
|
|
|
7
8
|
import { useIsMobile } from '@/hooks/useIsMobile';
|
|
8
9
|
import { ChatModelCard } from '@/types/llm';
|
|
9
10
|
|
|
10
|
-
import { AiModelType } from '../../../../../../../../../packages/model-bank/src/types/aiModel';
|
|
11
|
-
|
|
12
11
|
interface ModelConfigFormProps {
|
|
13
12
|
idEditable?: boolean;
|
|
14
13
|
initialValues?: ChatModelCard;
|
|
@@ -3,6 +3,7 @@ import { ActionIcon, Tag, Text, copyToClipboard } from '@lobehub/ui';
|
|
|
3
3
|
import { App, Switch } from 'antd';
|
|
4
4
|
import { createStyles, useTheme } from 'antd-style';
|
|
5
5
|
import { LucidePencil, TrashIcon } from 'lucide-react';
|
|
6
|
+
import { AiModelSourceEnum, AiProviderModelListItem } from 'model-bank';
|
|
6
7
|
import { memo, use, useState } from 'react';
|
|
7
8
|
import { useTranslation } from 'react-i18next';
|
|
8
9
|
import { Flexbox } from 'react-layout-kit';
|
|
@@ -17,10 +18,6 @@ import {
|
|
|
17
18
|
getTextOutputUnitRate,
|
|
18
19
|
} from '@/utils/pricing';
|
|
19
20
|
|
|
20
|
-
import {
|
|
21
|
-
AiModelSourceEnum,
|
|
22
|
-
AiProviderModelListItem,
|
|
23
|
-
} from '../../../../../../../../packages/model-bank/src/types/aiModel';
|
|
24
21
|
import ModelConfigModal from './ModelConfigModal';
|
|
25
22
|
import { ProviderSettingsContext } from './ProviderSettingsContext';
|
|
26
23
|
|
package/src/app/[variants]/(main)/settings/provider/features/ModelList/SortModelModal/ListItem.tsx
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { ModelIcon } from '@lobehub/icons';
|
|
2
2
|
import { SortableList } from '@lobehub/ui';
|
|
3
|
+
import { AiProviderModelListItem } from 'model-bank';
|
|
3
4
|
import { memo } from 'react';
|
|
4
5
|
import { Flexbox } from 'react-layout-kit';
|
|
5
6
|
|
|
6
|
-
import { AiProviderModelListItem } from '../../../../../../../../../packages/model-bank/src/types/aiModel';
|
|
7
|
-
|
|
8
7
|
const ListItem = memo<AiProviderModelListItem>(({ id, displayName }) => {
|
|
9
8
|
return (
|
|
10
9
|
<>
|
package/src/app/[variants]/(main)/settings/provider/features/ModelList/SortModelModal/index.tsx
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Button, Modal, SortableList } from '@lobehub/ui';
|
|
2
2
|
import { App } from 'antd';
|
|
3
3
|
import { createStyles } from 'antd-style';
|
|
4
|
+
import { AiProviderModelListItem } from 'model-bank';
|
|
4
5
|
import { memo, useState } from 'react';
|
|
5
6
|
import { useTranslation } from 'react-i18next';
|
|
6
7
|
import { Flexbox } from 'react-layout-kit';
|
|
7
8
|
|
|
8
9
|
import { useAiInfraStore } from '@/store/aiInfra';
|
|
9
10
|
|
|
10
|
-
import { AiProviderModelListItem } from '../../../../../../../../../packages/model-bank/src/types/aiModel';
|
|
11
11
|
import ListItem from './ListItem';
|
|
12
12
|
|
|
13
13
|
const useStyles = createStyles(({ css, token }) => ({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useResponsive } from 'antd-style';
|
|
4
|
-
import { memo,
|
|
4
|
+
import { memo, useRef, useState } from 'react';
|
|
5
5
|
import { Flexbox } from 'react-layout-kit';
|
|
6
6
|
|
|
7
7
|
import Actions from './components/Actions';
|
|
@@ -37,14 +37,12 @@ const ChatItem = memo<ChatItemProps>(
|
|
|
37
37
|
onEditingChange,
|
|
38
38
|
messageExtra,
|
|
39
39
|
renderMessage,
|
|
40
|
-
text,
|
|
41
40
|
errorMessage,
|
|
42
41
|
onDoubleClick,
|
|
43
|
-
fontSize,
|
|
44
42
|
aboveMessage,
|
|
45
43
|
belowMessage,
|
|
46
44
|
markdownProps,
|
|
47
|
-
|
|
45
|
+
id,
|
|
48
46
|
...rest
|
|
49
47
|
}) => {
|
|
50
48
|
const { mobile } = useResponsive();
|
|
@@ -61,37 +59,10 @@ const ChatItem = memo<ChatItemProps>(
|
|
|
61
59
|
// 在 ChatItem 组件中添加
|
|
62
60
|
const contentRef = useRef<HTMLDivElement>(null);
|
|
63
61
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
64
|
-
const [layoutMode
|
|
65
|
-
|
|
62
|
+
const [layoutMode] = useState<'horizontal' | 'vertical'>(
|
|
63
|
+
placement === 'right' ? 'horizontal' : 'vertical',
|
|
66
64
|
);
|
|
67
65
|
|
|
68
|
-
// 使用 ResizeObserver 监控内容和容器尺寸
|
|
69
|
-
useEffect(() => {
|
|
70
|
-
if (variant === 'docs') {
|
|
71
|
-
setLayoutMode('vertical');
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (!contentRef.current || !containerRef.current) return;
|
|
76
|
-
|
|
77
|
-
const observer = new ResizeObserver(() => {
|
|
78
|
-
if (!contentRef.current || !containerRef.current) return;
|
|
79
|
-
|
|
80
|
-
const containerWidth = containerRef.current.clientWidth;
|
|
81
|
-
const contentWidth = contentRef.current.scrollWidth; // 使用scrollWidth获取实际内容宽度
|
|
82
|
-
|
|
83
|
-
// 预留给Actions的最小空间 (根据实际Actions大小调整)
|
|
84
|
-
|
|
85
|
-
// 只有当内容宽度 + Actions最小宽度 > 容器宽度时才切换布局
|
|
86
|
-
setLayoutMode(contentWidth + actionsWrapWidth > containerWidth ? 'vertical' : 'horizontal');
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
observer.observe(contentRef.current);
|
|
90
|
-
observer.observe(containerRef.current);
|
|
91
|
-
|
|
92
|
-
return () => observer.disconnect();
|
|
93
|
-
}, [variant, actionsWrapWidth]);
|
|
94
|
-
|
|
95
66
|
return (
|
|
96
67
|
<Flexbox
|
|
97
68
|
className={cx(styles.container, className)}
|
|
@@ -139,7 +110,7 @@ const ChatItem = memo<ChatItemProps>(
|
|
|
139
110
|
) : (
|
|
140
111
|
<MessageContent
|
|
141
112
|
editing={editing}
|
|
142
|
-
|
|
113
|
+
id={id!}
|
|
143
114
|
markdownProps={markdownProps}
|
|
144
115
|
message={message}
|
|
145
116
|
messageExtra={
|
|
@@ -156,7 +127,6 @@ const ChatItem = memo<ChatItemProps>(
|
|
|
156
127
|
placement={placement}
|
|
157
128
|
primary={primary}
|
|
158
129
|
renderMessage={renderMessage}
|
|
159
|
-
text={text}
|
|
160
130
|
variant={variant}
|
|
161
131
|
/>
|
|
162
132
|
)}
|