@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.
Files changed (116) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/changelog/v1.json +9 -0
  3. package/package.json +2 -2
  4. package/packages/const/src/index.ts +1 -0
  5. package/packages/const/src/settings/index.ts +1 -0
  6. package/packages/model-bank/src/aiModels/aihubmix.ts +25 -0
  7. package/packages/model-bank/src/aiModels/nvidia.ts +17 -1
  8. package/packages/model-bank/src/aiModels/openai.ts +80 -1
  9. package/packages/model-runtime/src/const/models.ts +2 -0
  10. package/packages/model-runtime/src/providers/openai/index.ts +15 -11
  11. package/packages/model-runtime/src/providers/openrouter/index.ts +7 -2
  12. package/packages/model-runtime/src/providers/openrouter/type.ts +4 -2
  13. package/packages/model-runtime/src/providers/vercelaigateway/index.ts +7 -0
  14. package/packages/model-runtime/src/utils/modelParse.ts +31 -3
  15. package/packages/types/src/aiProvider.ts +1 -2
  16. package/packages/types/src/discover/models.ts +3 -2
  17. package/packages/types/src/discover/providers.ts +3 -2
  18. package/packages/types/src/message/chat.ts +13 -0
  19. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/index.tsx +1 -5
  20. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/WelcomeMessage.tsx +1 -1
  21. package/src/app/[variants]/(main)/settings/provider/features/ModelList/CreateNewModelModal/Form.tsx +1 -2
  22. package/src/app/[variants]/(main)/settings/provider/features/ModelList/ModelItem.tsx +1 -4
  23. package/src/app/[variants]/(main)/settings/provider/features/ModelList/SortModelModal/ListItem.tsx +1 -2
  24. package/src/app/[variants]/(main)/settings/provider/features/ModelList/SortModelModal/index.tsx +1 -1
  25. package/src/{components → features}/ChatItem/ChatItem.tsx +5 -35
  26. package/src/{components → features}/ChatItem/components/MessageContent.tsx +27 -7
  27. package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeArtifact/Render/index.tsx +1 -1
  28. package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/getNodeContent.test.ts +1 -1
  29. package/src/features/Conversation/{Actions → Messages/Assistant/Actions}/Error.tsx +1 -1
  30. package/src/features/Conversation/{components/ChatItem/ActionsBar.tsx → Messages/Assistant/Actions/index.tsx} +71 -44
  31. package/src/features/Conversation/Messages/Assistant/Block.tsx +63 -0
  32. package/src/features/Conversation/{Extras/Assistant.test.tsx → Messages/Assistant/Extra/index.test.tsx} +36 -31
  33. package/src/features/Conversation/{Extras/Assistant.tsx → Messages/Assistant/Extra/index.tsx} +13 -7
  34. package/src/features/Conversation/Messages/Assistant/MessageContent.tsx +102 -0
  35. package/src/features/Conversation/Messages/Assistant/index.tsx +235 -84
  36. package/src/features/Conversation/Messages/User/Actions.tsx +153 -0
  37. package/src/features/Conversation/Messages/User/BelowMessage.tsx +7 -2
  38. package/src/features/Conversation/{Extras/User.tsx → Messages/User/Extra.tsx} +9 -7
  39. package/src/features/Conversation/Messages/User/MessageContent.tsx +31 -0
  40. package/src/features/Conversation/Messages/User/index.tsx +127 -24
  41. package/src/features/Conversation/Messages/index.tsx +152 -0
  42. package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/ModelCard.tsx +4 -3
  43. package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/pricing.ts +3 -2
  44. package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/tokens.test.ts +2 -3
  45. package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareImage/Preview.tsx +1 -1
  46. package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareText/index.tsx +1 -1
  47. package/src/features/Conversation/components/VirtualizedList/index.tsx +1 -0
  48. package/src/features/Conversation/hooks/useChatListActionsBar.tsx +29 -1
  49. package/src/features/Conversation/hooks/useDoubleClickEdit.ts +42 -0
  50. package/src/features/Conversation/index.ts +1 -1
  51. package/src/features/Conversation/types/{index.tsx → index.ts} +0 -7
  52. package/src/features/Portal/Thread/Chat/ChatItem.tsx +0 -7
  53. package/src/hooks/useUserAvatar.test.ts +129 -0
  54. package/src/hooks/useUserAvatar.ts +19 -0
  55. package/src/server/routers/lambda/aiModel.ts +7 -8
  56. package/src/store/user/slices/settings/selectors/settings.ts +6 -5
  57. package/src/features/ChatItem/index.tsx +0 -58
  58. package/src/features/Conversation/Actions/Assistant.tsx +0 -68
  59. package/src/features/Conversation/Actions/Fallback.tsx +0 -19
  60. package/src/features/Conversation/Actions/Tool.tsx +0 -33
  61. package/src/features/Conversation/Actions/User.tsx +0 -39
  62. package/src/features/Conversation/Actions/customAction.ts +0 -37
  63. package/src/features/Conversation/Actions/index.ts +0 -14
  64. package/src/features/Conversation/Extras/index.ts +0 -8
  65. package/src/features/Conversation/Extras/type.ts +0 -5
  66. package/src/features/Conversation/Messages/index.ts +0 -45
  67. package/src/features/Conversation/components/ChatItem/index.tsx +0 -358
  68. /package/src/{components → features}/ChatItem/components/Actions.tsx +0 -0
  69. /package/src/{components → features}/ChatItem/components/Avatar.tsx +0 -0
  70. /package/src/{components → features}/ChatItem/components/BorderSpacing.tsx +0 -0
  71. /package/src/{components → features}/ChatItem/components/ErrorContent.tsx +0 -0
  72. /package/src/{components → features}/ChatItem/components/Loading.tsx +0 -0
  73. /package/src/{components → features}/ChatItem/components/Title.tsx +0 -0
  74. /package/src/{components → features}/ChatItem/index.ts +0 -0
  75. /package/src/{components → features}/ChatItem/style.ts +0 -0
  76. /package/src/{components → features}/ChatItem/type.ts +0 -0
  77. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeArtifact/Render/Icon.tsx +0 -0
  78. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeArtifact/index.ts +0 -0
  79. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeArtifact/rehypePlugin.test.ts +0 -0
  80. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeArtifact/rehypePlugin.ts +0 -0
  81. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeThinking/Render.tsx +0 -0
  82. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeThinking/index.ts +0 -0
  83. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LocalFile/Render/index.tsx +0 -0
  84. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LocalFile/index.ts +0 -0
  85. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/Thinking/Render.tsx +0 -0
  86. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/Thinking/index.ts +0 -0
  87. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/index.ts +0 -0
  88. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/__snapshots__/createRemarkSelfClosingTagPlugin.test.ts.snap +0 -0
  89. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/createRemarkCustomTagPlugin.ts +0 -0
  90. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/createRemarkSelfClosingTagPlugin.test.ts +0 -0
  91. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/createRemarkSelfClosingTagPlugin.ts +0 -0
  92. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/getNodeContent.ts +0 -0
  93. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/type.ts +0 -0
  94. /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/utils.ts +0 -0
  95. /package/src/features/Conversation/{Extras → components/Extras}/ExtraContainer.tsx +0 -0
  96. /package/src/features/Conversation/{Extras → components/Extras}/TTS/FilePlayer.tsx +0 -0
  97. /package/src/features/Conversation/{Extras → components/Extras}/TTS/InitPlayer.tsx +0 -0
  98. /package/src/features/Conversation/{Extras → components/Extras}/TTS/Player.tsx +0 -0
  99. /package/src/features/Conversation/{Extras → components/Extras}/TTS/index.tsx +0 -0
  100. /package/src/features/Conversation/{Extras → components/Extras}/Translate.tsx +0 -0
  101. /package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/TokenProgress.tsx +0 -0
  102. /package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/index.tsx +0 -0
  103. /package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/tokens.ts +0 -0
  104. /package/src/features/Conversation/{Extras → components/Extras}/Usage/index.tsx +0 -0
  105. /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareImage/index.tsx +0 -0
  106. /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareImage/style.ts +0 -0
  107. /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareImage/type.ts +0 -0
  108. /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareText/Preview.tsx +0 -0
  109. /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareText/template.test.ts +0 -0
  110. /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareText/template.ts +0 -0
  111. /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareText/type.ts +0 -0
  112. /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/index.tsx +0 -0
  113. /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/style.ts +0 -0
  114. /package/src/features/Conversation/{components/ChatItem → context}/InPortalThreadContext.ts +0 -0
  115. /package/src/features/Conversation/{components/ChatItem/utils.test.ts → utils.test.ts} +0 -0
  116. /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
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#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
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "improvements": [
5
+ "Add GPT-5 pro model."
6
+ ]
7
+ },
8
+ "date": "2025-10-07",
9
+ "version": "1.135.4"
10
+ },
2
11
  {
3
12
  "children": {
4
13
  "improvements": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.135.3",
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": "~6.9.0",
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",
@@ -5,6 +5,7 @@ export * from './desktop';
5
5
  export * from './guide';
6
6
  export * from './layoutTokens';
7
7
  export * from './message';
8
+ export * from './meta';
8
9
  export * from './session';
9
10
  export * from './settings';
10
11
  export * from './trace';
@@ -9,6 +9,7 @@ import { DEFAULT_TOOL_CONFIG } from './tool';
9
9
  import { DEFAULT_TTS_CONFIG } from './tts';
10
10
 
11
11
  export * from './agent';
12
+ export * from './common';
12
13
  export * from './group';
13
14
  export * from './hotkey';
14
15
  export * from './llm';
@@ -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', // deprecated on 2025-10-10
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
  {
@@ -36,6 +36,8 @@ export const responsesAPIModels = new Set([
36
36
  'computer-use-preview',
37
37
  'computer-use-preview-2025-03-11',
38
38
  'gpt-5-codex',
39
+ 'gpt-5-pro',
40
+ 'gpt-5-pro-2025-10-06',
39
41
  ]);
40
42
 
41
43
  /**
@@ -81,23 +81,27 @@ export const LobeOpenAI = createOpenAICompatibleRuntime({
81
81
 
82
82
  const openaiTools = enabledSearch
83
83
  ? [
84
- ...(tools || []),
85
- {
86
- type: 'web_search',
87
- ...(oaiSearchContextSize && {
88
- search_context_size: oaiSearchContextSize,
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: payload.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: string) => {
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,
@@ -1,8 +1,10 @@
1
1
  interface ModelPricing {
2
2
  completion: string;
3
- image: string;
3
+ image?: string;
4
+ input_cache_read?: string;
5
+ input_cache_write?: string;
4
6
  prompt: string;
5
- request: string;
7
+ request?: string;
6
8
  }
7
9
 
8
10
  export interface OpenRouterModelCard {
@@ -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?: { input?: number; output?: number; units?: any[] }) => {
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 (typeof input !== 'number' && typeof output !== 'number') return undefined;
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 '../../../model-bank/src/types/aiModel';
2
- import { ModelProviderCard } from '@/types/llm';
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 '../../../model-bank/src/types/aiModel';
2
- import { ModelProviderCard } from '@/types/llm';
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, useMemo } from 'react';
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';
@@ -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
 
@@ -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
  <>
@@ -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, useEffect, useRef, useState } from 'react';
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
- actionsWrapWidth = 54,
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, setLayoutMode] = useState<'horizontal' | 'vertical'>(
65
- variant === 'bubble' ? 'horizontal' : 'vertical',
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
- fontSize={fontSize}
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
  )}