@lobehub/lobehub 2.0.0-next.1 → 2.0.0-next.10

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 (242) hide show
  1. package/.github/workflows/desktop-pr-build.yml +12 -10
  2. package/.github/workflows/docker.yml +25 -20
  3. package/.github/workflows/e2e.yml +3 -3
  4. package/.github/workflows/release-desktop-beta.yml +8 -8
  5. package/.github/workflows/release.yml +1 -1
  6. package/.github/workflows/test.yml +4 -4
  7. package/CHANGELOG.md +236 -0
  8. package/apps/desktop/src/main/utils/next-electron-rsc.ts +7 -5
  9. package/changelog/v1.json +73 -0
  10. package/docs/development/database-schema.dbml +11 -1
  11. package/docs/self-hosting/advanced/auth/next-auth/auth0.mdx +2 -2
  12. package/docs/self-hosting/advanced/auth/next-auth/auth0.zh-CN.mdx +2 -2
  13. package/docs/self-hosting/advanced/auth/next-auth/authelia.mdx +2 -2
  14. package/docs/self-hosting/advanced/auth/next-auth/authelia.zh-CN.mdx +2 -2
  15. package/docs/self-hosting/advanced/auth/next-auth/authentik.mdx +2 -2
  16. package/docs/self-hosting/advanced/auth/next-auth/authentik.zh-CN.mdx +2 -2
  17. package/docs/self-hosting/advanced/auth/next-auth/casdoor.mdx +2 -2
  18. package/docs/self-hosting/advanced/auth/next-auth/casdoor.zh-CN.mdx +2 -2
  19. package/docs/self-hosting/advanced/auth/next-auth/cloudflare-zero-trust.mdx +2 -2
  20. package/docs/self-hosting/advanced/auth/next-auth/cloudflare-zero-trust.zh-CN.mdx +2 -2
  21. package/docs/self-hosting/advanced/auth/next-auth/github.mdx +2 -2
  22. package/docs/self-hosting/advanced/auth/next-auth/github.zh-CN.mdx +2 -2
  23. package/docs/self-hosting/advanced/auth/next-auth/google.mdx +32 -29
  24. package/docs/self-hosting/advanced/auth/next-auth/keycloak.mdx +2 -2
  25. package/docs/self-hosting/advanced/auth/next-auth/keycloak.zh-CN.mdx +2 -2
  26. package/docs/self-hosting/advanced/auth/next-auth/logto.mdx +5 -3
  27. package/docs/self-hosting/advanced/auth/next-auth/logto.zh-CN.mdx +5 -3
  28. package/docs/self-hosting/advanced/auth/next-auth/microsoft-entra-id.mdx +2 -2
  29. package/docs/self-hosting/advanced/auth/next-auth/microsoft-entra-id.zh-CN.mdx +2 -2
  30. package/docs/self-hosting/advanced/auth/next-auth/okta.mdx +2 -2
  31. package/docs/self-hosting/advanced/auth/next-auth/okta.zh-CN.mdx +2 -2
  32. package/docs/self-hosting/advanced/auth/next-auth/wechat.mdx +2 -2
  33. package/docs/self-hosting/advanced/auth/next-auth/wechat.zh-CN.mdx +2 -2
  34. package/docs/self-hosting/advanced/auth/next-auth/zitadel.mdx +2 -2
  35. package/docs/self-hosting/advanced/auth/next-auth/zitadel.zh-CN.mdx +2 -2
  36. package/docs/self-hosting/advanced/auth.mdx +32 -21
  37. package/docs/self-hosting/advanced/auth.zh-CN.mdx +30 -19
  38. package/docs/self-hosting/advanced/online-search.mdx +30 -25
  39. package/docs/self-hosting/advanced/online-search.zh-CN.mdx +25 -23
  40. package/locales/ar/models.json +15 -6
  41. package/locales/bg-BG/models.json +15 -6
  42. package/locales/de-DE/models.json +15 -6
  43. package/locales/en-US/models.json +15 -6
  44. package/locales/es-ES/models.json +15 -6
  45. package/locales/fa-IR/models.json +15 -6
  46. package/locales/fr-FR/models.json +15 -6
  47. package/locales/it-IT/models.json +15 -6
  48. package/locales/ja-JP/models.json +15 -6
  49. package/locales/ko-KR/models.json +15 -6
  50. package/locales/nl-NL/models.json +15 -6
  51. package/locales/pl-PL/models.json +15 -6
  52. package/locales/pt-BR/models.json +15 -6
  53. package/locales/ru-RU/models.json +15 -6
  54. package/locales/tr-TR/models.json +15 -6
  55. package/locales/vi-VN/models.json +15 -6
  56. package/locales/zh-CN/models.json +15 -6
  57. package/locales/zh-TW/models.json +15 -6
  58. package/next.config.ts +2 -3
  59. package/package.json +13 -19
  60. package/packages/const/src/index.ts +0 -1
  61. package/packages/const/src/models.ts +13 -0
  62. package/packages/const/src/url.ts +1 -4
  63. package/packages/context-engine/src/index.ts +1 -6
  64. package/packages/context-engine/src/processors/GroupMessageFlatten.ts +12 -2
  65. package/packages/context-engine/src/processors/__tests__/GroupMessageFlatten.test.ts +73 -9
  66. package/packages/context-engine/src/providers/index.ts +0 -2
  67. package/packages/database/migrations/0041_improve_index.sql +10 -0
  68. package/packages/database/migrations/meta/0041_snapshot.json +7784 -0
  69. package/packages/database/migrations/meta/_journal.json +7 -0
  70. package/packages/database/package.json +1 -1
  71. package/packages/database/src/core/migrations.json +17 -0
  72. package/packages/database/src/models/__tests__/message.grouping.test.ts +812 -0
  73. package/packages/database/src/models/__tests__/message.test.ts +322 -170
  74. package/packages/database/src/models/message.ts +62 -24
  75. package/packages/database/src/models/session.ts +60 -19
  76. package/packages/database/src/schemas/agent.ts +10 -11
  77. package/packages/database/src/schemas/message.ts +5 -1
  78. package/packages/database/src/schemas/relations.ts +6 -4
  79. package/packages/database/src/schemas/session.ts +2 -0
  80. package/packages/database/src/schemas/topic.ts +6 -1
  81. package/packages/database/src/utils/__tests__/groupMessages.test.ts +145 -2
  82. package/packages/database/src/utils/groupMessages.ts +7 -5
  83. package/packages/electron-client-ipc/package.json +4 -1
  84. package/packages/file-loaders/package.json +1 -0
  85. package/packages/model-bank/src/aiModels/anthropic.ts +0 -63
  86. package/packages/model-bank/src/aiModels/azure.ts +155 -0
  87. package/packages/model-bank/src/aiModels/bedrock.ts +44 -0
  88. package/packages/model-bank/src/aiModels/higress.ts +0 -55
  89. package/packages/model-bank/src/aiModels/infiniai.ts +21 -0
  90. package/packages/model-bank/src/aiModels/ollamacloud.ts +13 -0
  91. package/packages/model-bank/src/aiModels/siliconcloud.ts +19 -0
  92. package/packages/model-runtime/src/core/openaiCompatibleFactory/createImage.ts +1 -1
  93. package/packages/model-runtime/src/core/openaiCompatibleFactory/index.test.ts +33 -3
  94. package/packages/model-runtime/src/core/parameterResolver.ts +3 -0
  95. package/packages/model-runtime/src/core/streams/openai/__snapshots__/responsesStream.test.ts.snap +0 -38
  96. package/packages/model-runtime/src/providers/azureOpenai/index.ts +2 -1
  97. package/packages/model-runtime/src/providers/minimax/index.ts +5 -5
  98. package/packages/model-runtime/src/providers/search1api/index.test.ts +2 -2
  99. package/packages/types/src/message/common/base.ts +13 -0
  100. package/packages/types/src/message/common/image.ts +8 -0
  101. package/packages/types/src/message/common/metadata.ts +39 -0
  102. package/packages/types/src/message/common/tools.ts +10 -0
  103. package/packages/types/src/message/db/params.ts +47 -1
  104. package/packages/types/src/message/ui/chat.ts +4 -1
  105. package/packages/types/src/search.ts +16 -0
  106. package/packages/web-crawler/src/crawImpl/firecrawl.ts +39 -12
  107. package/scripts/migrateServerDB/index.ts +2 -1
  108. package/src/app/(backend)/oidc/consent/route.ts +0 -1
  109. package/src/app/(backend)/webapi/revalidate/route.ts +1 -1
  110. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/V1Mobile/index.tsx +2 -2
  111. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/V1Mobile/useSend.ts +6 -4
  112. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/useSend.ts +15 -10
  113. package/src/app/[variants]/(main)/chat/@session/features/SessionListContent/List/Item/index.tsx +4 -2
  114. package/src/app/[variants]/(main)/settings/_layout/SettingsContent.tsx +0 -3
  115. package/src/app/[variants]/layout.tsx +1 -0
  116. package/src/app/sitemap.tsx +7 -1
  117. package/src/components/Thinking/index.tsx +4 -3
  118. package/src/config/modelProviders/anthropic.ts +0 -23
  119. package/src/config/modelProviders/higress.ts +0 -23
  120. package/src/config/modelProviders/minimax.ts +1 -1
  121. package/src/config/modelProviders/qiniu.ts +1 -1
  122. package/src/envs/auth.ts +0 -179
  123. package/src/features/AgentSetting/AgentPlugin/index.tsx +21 -13
  124. package/src/features/ChatInput/ActionBar/STT/browser.tsx +2 -2
  125. package/src/features/ChatInput/ActionBar/STT/openai.tsx +2 -2
  126. package/src/features/ChatInput/ActionBar/Tools/useControls.tsx +1 -3
  127. package/src/features/Conversation/Error/ErrorJsonViewer.tsx +4 -3
  128. package/src/features/Conversation/Error/OllamaBizError/index.tsx +7 -2
  129. package/src/features/Conversation/Error/index.tsx +15 -5
  130. package/src/features/Conversation/MarkdownElements/LobeArtifact/Render/index.tsx +2 -2
  131. package/src/features/Conversation/Messages/Assistant/Extra/index.tsx +2 -2
  132. package/src/features/Conversation/Messages/Assistant/MessageContent.tsx +5 -3
  133. package/src/features/Conversation/Messages/Assistant/Tool/Inspector/BuiltinPluginTitle.tsx +2 -2
  134. package/src/features/Conversation/Messages/Assistant/Tool/Inspector/ToolTitle.tsx +4 -2
  135. package/src/features/Conversation/Messages/Assistant/Tool/Render/CustomRender.tsx +2 -2
  136. package/src/features/Conversation/Messages/Assistant/Tool/Render/index.tsx +2 -2
  137. package/src/features/Conversation/Messages/Assistant/Tool/index.tsx +2 -2
  138. package/src/features/Conversation/Messages/Assistant/index.tsx +4 -4
  139. package/src/features/Conversation/Messages/Default.tsx +2 -2
  140. package/src/features/Conversation/Messages/User/Extra.tsx +2 -2
  141. package/src/features/Conversation/Messages/User/index.tsx +4 -4
  142. package/src/features/Conversation/Messages/index.tsx +3 -3
  143. package/src/features/Conversation/components/AutoScroll.tsx +2 -2
  144. package/src/features/Conversation/components/Extras/Usage/UsageDetail/index.tsx +9 -6
  145. package/src/features/PluginTag/index.tsx +1 -3
  146. package/src/features/PluginsUI/Render/BuiltinType/index.test.tsx +37 -28
  147. package/src/features/Portal/Artifacts/Body/index.tsx +2 -2
  148. package/src/libs/next-auth/auth.config.ts +1 -1
  149. package/src/libs/next-auth/sso-providers/auth0.ts +0 -7
  150. package/src/libs/next-auth/sso-providers/authelia.ts +3 -5
  151. package/src/libs/next-auth/sso-providers/authentik.ts +0 -7
  152. package/src/libs/next-auth/sso-providers/cloudflare-zero-trust.ts +3 -6
  153. package/src/libs/next-auth/sso-providers/cognito.ts +1 -5
  154. package/src/libs/next-auth/sso-providers/generic-oidc.ts +3 -5
  155. package/src/libs/next-auth/sso-providers/github.ts +0 -6
  156. package/src/libs/next-auth/sso-providers/google.ts +0 -2
  157. package/src/libs/next-auth/sso-providers/index.ts +0 -2
  158. package/src/libs/next-auth/sso-providers/keycloak.ts +0 -3
  159. package/src/libs/next-auth/sso-providers/logto.ts +3 -5
  160. package/src/libs/next-auth/sso-providers/okta.ts +0 -4
  161. package/src/libs/next-auth/sso-providers/zitadel.ts +0 -7
  162. package/src/libs/oidc-provider/provider.ts +1 -1
  163. package/src/server/modules/AssistantStore/index.ts +1 -1
  164. package/src/server/modules/ModelRuntime/trace.ts +11 -4
  165. package/src/server/routers/lambda/message.ts +14 -3
  166. package/src/server/routers/lambda/session.ts +8 -5
  167. package/src/server/services/search/impls/firecrawl/index.ts +51 -11
  168. package/src/server/services/search/impls/firecrawl/type.ts +60 -9
  169. package/src/services/chat/chat.test.ts +1 -40
  170. package/src/services/chat/contextEngineering.test.ts +0 -30
  171. package/src/services/chat/contextEngineering.ts +1 -12
  172. package/src/services/chat/index.ts +2 -7
  173. package/src/services/chat/types.ts +1 -1
  174. package/src/services/message/_deprecated.ts +1 -1
  175. package/src/services/message/client.ts +8 -2
  176. package/src/services/message/server.ts +7 -2
  177. package/src/services/message/type.ts +6 -1
  178. package/src/services/user/client.test.ts +4 -1
  179. package/src/store/chat/helpers.test.ts +99 -0
  180. package/src/store/chat/helpers.ts +21 -2
  181. package/src/store/chat/selectors.ts +1 -1
  182. package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +3 -3
  183. package/src/store/chat/slices/builtinTool/actions/index.ts +1 -4
  184. package/src/store/chat/slices/message/action.test.ts +5 -1
  185. package/src/store/chat/slices/message/action.ts +102 -14
  186. package/src/store/chat/slices/message/reducer.test.ts +363 -5
  187. package/src/store/chat/slices/message/reducer.ts +87 -3
  188. package/src/store/chat/slices/message/{selectors.test.ts → selectors/chat.test.ts} +266 -30
  189. package/src/store/chat/slices/message/{selectors.ts → selectors/chat.ts} +29 -79
  190. package/src/store/chat/slices/message/selectors/index.ts +2 -0
  191. package/src/store/chat/slices/message/selectors/messageState.test.ts +36 -0
  192. package/src/store/chat/slices/message/selectors/messageState.ts +80 -0
  193. package/src/store/chat/slices/plugin/action.test.ts +34 -132
  194. package/src/store/chat/slices/plugin/action.ts +1 -44
  195. package/src/store/tool/selectors/tool.test.ts +1 -1
  196. package/src/store/tool/selectors/tool.ts +6 -8
  197. package/src/store/tool/slices/builtin/action.test.ts +83 -35
  198. package/src/store/tool/slices/builtin/action.ts +0 -9
  199. package/src/store/tool/slices/builtin/selectors.test.ts +4 -30
  200. package/src/store/tool/slices/builtin/selectors.ts +15 -21
  201. package/src/tools/index.ts +0 -6
  202. package/src/tools/renders.ts +0 -3
  203. package/src/tools/web-browsing/Portal/Search/Footer.tsx +2 -2
  204. package/tsconfig.json +9 -2
  205. package/packages/const/src/guide.ts +0 -89
  206. package/packages/context-engine/src/providers/InboxGuide.ts +0 -102
  207. package/packages/context-engine/src/providers/__tests__/InboxGuideProvider.test.ts +0 -121
  208. package/src/app/[variants]/(main)/settings/llm/ProviderList/Azure/index.tsx +0 -93
  209. package/src/app/[variants]/(main)/settings/llm/ProviderList/Bedrock/index.tsx +0 -70
  210. package/src/app/[variants]/(main)/settings/llm/ProviderList/Cloudflare/index.tsx +0 -39
  211. package/src/app/[variants]/(main)/settings/llm/ProviderList/Github/index.tsx +0 -52
  212. package/src/app/[variants]/(main)/settings/llm/ProviderList/HuggingFace/index.tsx +0 -52
  213. package/src/app/[variants]/(main)/settings/llm/ProviderList/Ollama/index.tsx +0 -20
  214. package/src/app/[variants]/(main)/settings/llm/ProviderList/OpenAI/index.tsx +0 -17
  215. package/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx +0 -132
  216. package/src/app/[variants]/(main)/settings/llm/components/Checker.tsx +0 -118
  217. package/src/app/[variants]/(main)/settings/llm/components/ProviderConfig/index.tsx +0 -303
  218. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/CustomModelOption.tsx +0 -98
  219. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelConfigModal/Form.tsx +0 -104
  220. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelConfigModal/index.tsx +0 -77
  221. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/ModelFetcher.tsx +0 -105
  222. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/Option.tsx +0 -68
  223. package/src/app/[variants]/(main)/settings/llm/components/ProviderModelList/index.tsx +0 -146
  224. package/src/app/[variants]/(main)/settings/llm/const.ts +0 -20
  225. package/src/app/[variants]/(main)/settings/llm/features/Footer.tsx +0 -35
  226. package/src/app/[variants]/(main)/settings/llm/index.tsx +0 -30
  227. package/src/app/[variants]/(main)/settings/llm/type.ts +0 -5
  228. package/src/envs/__tests__/auth.test.ts +0 -200
  229. package/src/libs/next-auth/sso-providers/azure-ad.ts +0 -33
  230. package/src/services/chat/__snapshots__/chat.test.ts.snap +0 -110
  231. package/src/store/chat/slices/builtinTool/actions/__tests__/dalle.test.ts +0 -121
  232. package/src/store/chat/slices/builtinTool/actions/dalle.ts +0 -124
  233. package/src/tools/dalle/Render/GalleyGrid.tsx +0 -60
  234. package/src/tools/dalle/Render/Item/EditMode.tsx +0 -66
  235. package/src/tools/dalle/Render/Item/Error.tsx +0 -49
  236. package/src/tools/dalle/Render/Item/Image.tsx +0 -44
  237. package/src/tools/dalle/Render/Item/ImageFileItem.tsx +0 -57
  238. package/src/tools/dalle/Render/Item/index.tsx +0 -88
  239. package/src/tools/dalle/Render/ToolBar.tsx +0 -56
  240. package/src/tools/dalle/Render/index.tsx +0 -52
  241. package/src/tools/dalle/index.ts +0 -92
  242. /package/src/{middleware.ts → proxy.ts} +0 -0
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable sort-keys-fix/sort-keys-fix , typescript-sort-keys/interface */
2
+ import { z } from 'zod';
2
3
 
3
4
  export interface ModelTokensUsage {
4
5
  // Input tokens breakdown
@@ -38,6 +39,44 @@ export interface ModelTokensUsage {
38
39
  totalTokens?: number;
39
40
  }
40
41
 
42
+ export const ModelUsageSchema = z.object({
43
+ // Input tokens breakdown
44
+ inputCachedTokens: z.number().optional(),
45
+ inputCacheMissTokens: z.number().optional(),
46
+ inputWriteCacheTokens: z.number().optional(),
47
+ inputTextTokens: z.number().optional(),
48
+ inputImageTokens: z.number().optional(),
49
+ inputAudioTokens: z.number().optional(),
50
+ inputCitationTokens: z.number().optional(),
51
+
52
+ // Output tokens breakdown
53
+ outputTextTokens: z.number().optional(),
54
+ outputImageTokens: z.number().optional(),
55
+ outputAudioTokens: z.number().optional(),
56
+ outputReasoningTokens: z.number().optional(),
57
+
58
+ // Prediction tokens
59
+ acceptedPredictionTokens: z.number().optional(),
60
+ rejectedPredictionTokens: z.number().optional(),
61
+
62
+ // Total tokens
63
+ totalInputTokens: z.number().optional(),
64
+ totalOutputTokens: z.number().optional(),
65
+ totalTokens: z.number().optional(),
66
+
67
+ // Cost
68
+ cost: z.number().optional(),
69
+ });
70
+
71
+ export const ModelPerformanceSchema = z.object({
72
+ tps: z.number().optional(),
73
+ ttft: z.number().optional(),
74
+ duration: z.number().optional(),
75
+ latency: z.number().optional(),
76
+ });
77
+
78
+ export const MessageMetadataSchema = ModelUsageSchema.merge(ModelPerformanceSchema);
79
+
41
80
  export interface ModelUsage extends ModelTokensUsage {
42
81
  /**
43
82
  * dollar
@@ -16,6 +16,7 @@ export interface ChatToolPayload {
16
16
  arguments: string;
17
17
  id: string;
18
18
  identifier: string;
19
+ result_msg_id?: string;
19
20
  type: LobeToolRenderType;
20
21
  }
21
22
 
@@ -85,6 +86,15 @@ export const MessageToolCallSchema = z.object({
85
86
  type: z.string(),
86
87
  });
87
88
 
89
+ export const ChatToolPayloadSchema = z.object({
90
+ apiName: z.string(),
91
+ arguments: z.string(),
92
+ id: z.string(),
93
+ identifier: z.string(),
94
+ result_msg_id: z.string().optional(),
95
+ type: z.string(),
96
+ });
97
+
88
98
  /**
89
99
  * 聊天消息错误对象
90
100
  */
@@ -1,11 +1,20 @@
1
- import { GroundingSearch } from '../../search';
1
+ /* eslint-disable sort-keys-fix/sort-keys-fix */
2
+ import { z } from 'zod';
3
+
4
+ import { GroundingSearch, GroundingSearchSchema } from '../../search';
2
5
  import {
3
6
  ChatImageItem,
7
+ ChatImageItemSchema,
4
8
  ChatMessageError,
9
+ ChatMessageErrorSchema,
5
10
  ChatToolPayload,
11
+ ChatToolPayloadSchema,
6
12
  MessageMetadata,
13
+ MessageMetadataSchema,
7
14
  MessageToolCall,
15
+ MessageToolCallSchema,
8
16
  ModelReasoning,
17
+ ModelReasoningSchema,
9
18
  } from '../common';
10
19
  import { UIChatMessage } from '../ui';
11
20
 
@@ -34,6 +43,21 @@ export interface CreateMessageResult {
34
43
  messages: UIChatMessage[];
35
44
  }
36
45
 
46
+ /**
47
+ * Result type for updateMessage
48
+ * Contains success status and optional message list
49
+ */
50
+ export interface UpdateMessageResult {
51
+ /**
52
+ * Updated message list (only present when success is true and sessionId/topicId provided)
53
+ */
54
+ messages?: UIChatMessage[];
55
+ /**
56
+ * Whether the update was successful
57
+ */
58
+ success: boolean;
59
+ }
60
+
37
61
  export interface NewMessage {
38
62
  agentId?: string | null;
39
63
  clientId?: string | null;
@@ -67,12 +91,14 @@ export interface UpdateMessageParams {
67
91
  imageList?: ChatImageItem[];
68
92
  metadata?: MessageMetadata;
69
93
  model?: string;
94
+ observationId?: string;
70
95
  provider?: string;
71
96
  reasoning?: ModelReasoning;
72
97
  role?: string;
73
98
  search?: GroundingSearch;
74
99
  toolCalls?: MessageToolCall[];
75
100
  tools?: ChatToolPayload[] | null;
101
+ traceId?: string;
76
102
  }
77
103
 
78
104
  export interface NewMessageQueryParams {
@@ -81,3 +107,23 @@ export interface NewMessageQueryParams {
81
107
  rewriteQuery: string;
82
108
  userQuery: string;
83
109
  }
110
+
111
+ // ========== Zod Schemas ========== //
112
+
113
+ export const UpdateMessageParamsSchema = z
114
+ .object({
115
+ content: z.string().optional(),
116
+ error: ChatMessageErrorSchema.nullable().optional(),
117
+ imageList: z.array(ChatImageItemSchema).optional(),
118
+ metadata: MessageMetadataSchema.optional(),
119
+ model: z.string().optional(),
120
+ observationId: z.string().optional(),
121
+ provider: z.string().optional(),
122
+ reasoning: ModelReasoningSchema.optional(),
123
+ role: z.string().optional(),
124
+ search: GroundingSearchSchema.optional(),
125
+ toolCalls: z.array(MessageToolCallSchema).optional(),
126
+ tools: z.array(ChatToolPayloadSchema).nullable().optional(),
127
+ traceId: z.string().optional(),
128
+ })
129
+ .passthrough();
@@ -26,10 +26,11 @@ export interface ChatFileItem {
26
26
 
27
27
  export interface AssistantContentBlock {
28
28
  content: string;
29
- fileList?: ChatFileItem[];
29
+ error?: ChatMessageError | null;
30
30
  id: string;
31
31
  imageList?: ChatImageItem[];
32
32
  performance?: ModelPerformance;
33
+ reasoning?: ModelReasoning;
33
34
  tools?: ChatToolPayloadWithResult[];
34
35
  usage?: ModelUsage;
35
36
  }
@@ -62,6 +63,7 @@ export interface UIChatMessage {
62
63
  imageList?: ChatImageItem[];
63
64
  meta: MetaData;
64
65
  metadata?: MessageMetadata | null;
66
+ model?: string | null;
65
67
  /**
66
68
  * observation id
67
69
  */
@@ -78,6 +80,7 @@ export interface UIChatMessage {
78
80
  plugin?: ChatPluginPayload;
79
81
  pluginError?: any;
80
82
  pluginState?: any;
83
+ provider?: string | null;
81
84
  /**
82
85
  * quoted other message's id
83
86
  */
@@ -1,3 +1,5 @@
1
+ import { z } from 'zod';
2
+
1
3
  export type SearchMode = 'off' | 'auto' | 'on';
2
4
 
3
5
  export enum ModelSearchImplement {
@@ -27,3 +29,17 @@ export interface GroundingSearch {
27
29
  citations?: CitationItem[];
28
30
  searchQueries?: string[];
29
31
  }
32
+
33
+ export const GroundingSearchSchema = z.object({
34
+ citations: z
35
+ .array(
36
+ z.object({
37
+ favicon: z.string().optional(),
38
+ id: z.string().optional(),
39
+ title: z.string().optional(),
40
+ url: z.string(),
41
+ }),
42
+ )
43
+ .optional(),
44
+ searchQueries: z.array(z.string()).optional(),
45
+ });
@@ -3,36 +3,55 @@ import { NetworkConnectionError, PageNotFoundError, TimeoutError } from '../util
3
3
  import { DEFAULT_TIMEOUT, withTimeout } from '../utils/withTimeout';
4
4
 
5
5
  interface FirecrawlMetadata {
6
- description: string;
7
- keywords: string;
8
- language: string;
6
+ description?: string;
7
+ error?: string;
8
+ keywords?: string;
9
+ language?: string;
9
10
  ogDescription?: string;
10
11
  ogImage?: string;
11
12
  ogLocaleAlternate?: string[];
12
13
  ogSiteName?: string;
13
14
  ogTitle?: string;
14
15
  ogUrl?: string;
15
- robots: string;
16
- statusCode: number;
16
+ robots?: string;
17
17
  sourceURL: string;
18
- title: string;
18
+ statusCode: number;
19
+ title?: string;
19
20
  }
20
21
 
21
22
  interface FirecrawlResults {
23
+ actions?: {
24
+ javascriptReturns?: Array<{ type: string; value: any }>;
25
+ pdfs?: string[];
26
+ scrapes?: Array<{ html: string; url: string }>;
27
+ screenshots?: string[];
28
+ };
29
+ changeTracking?: {
30
+ changeStatus?: string;
31
+ diff?: string;
32
+ json?: Record<string, any>;
33
+ previousScrapeAt?: string;
34
+ visibility?: string;
35
+ };
22
36
  html?: string;
37
+ links?: string[];
23
38
  markdown?: string;
24
39
  metadata: FirecrawlMetadata;
40
+ rawHtml?: string;
41
+ screenshot?: string;
42
+ summary?: string;
43
+ warning?: string;
25
44
  }
26
45
 
27
46
  interface FirecrawlResponse {
28
- success: boolean;
29
47
  data: FirecrawlResults;
48
+ success: boolean;
30
49
  }
31
50
 
32
51
  export const firecrawl: CrawlImpl = async (url) => {
33
52
  // Get API key from environment variable
34
53
  const apiKey = process.env.FIRECRAWL_API_KEY;
35
- const baseUrl = process.env.FIRECRAWL_URL || 'https://api.firecrawl.dev/v1';
54
+ const baseUrl = process.env.FIRECRAWL_URL || 'https://api.firecrawl.dev/v2';
36
55
 
37
56
  let res: Response;
38
57
 
@@ -40,7 +59,7 @@ export const firecrawl: CrawlImpl = async (url) => {
40
59
  res = await withTimeout(
41
60
  fetch(`${baseUrl}/scrape`, {
42
61
  body: JSON.stringify({
43
- formats: ["markdown"], // ["markdown", "html"]
62
+ formats: ['markdown'], // ["markdown", "html"]
44
63
  url,
45
64
  }),
46
65
  headers: {
@@ -75,6 +94,14 @@ export const firecrawl: CrawlImpl = async (url) => {
75
94
  try {
76
95
  const data = (await res.json()) as FirecrawlResponse;
77
96
 
97
+ if (data.data.warning) {
98
+ console.warn('[Firecrawl] Warning:', data.data.warning);
99
+ }
100
+
101
+ if (data.data.metadata.error) {
102
+ console.error('[Firecrawl] Metadata error:', data.data.metadata.error);
103
+ }
104
+
78
105
  // Check if content is empty or too short
79
106
  if (!data.data.markdown || data.data.markdown.length < 100) {
80
107
  return;
@@ -83,14 +110,14 @@ export const firecrawl: CrawlImpl = async (url) => {
83
110
  return {
84
111
  content: data.data.markdown,
85
112
  contentType: 'text',
86
- description: data.data.metadata.description,
113
+ description: data.data.metadata.description || '',
87
114
  length: data.data.markdown.length,
88
115
  siteName: new URL(url).hostname,
89
- title: data.data.metadata.title,
116
+ title: data.data.metadata.title || '',
90
117
  url: url,
91
118
  } satisfies CrawlSuccessResult;
92
119
  } catch (error) {
93
- console.error(error);
120
+ console.error('[Firecrawl] Parse error:', error);
94
121
  }
95
122
 
96
123
  return;
@@ -17,13 +17,14 @@ const isDesktop = process.env.NEXT_PUBLIC_IS_DESKTOP_APP === '1';
17
17
  const runMigrations = async () => {
18
18
  const { serverDB } = await import('../../packages/database/src/server');
19
19
 
20
+ const time = Date.now();
20
21
  if (process.env.DATABASE_DRIVER === 'node') {
21
22
  await nodeMigrate(serverDB, { migrationsFolder });
22
23
  } else {
23
24
  await neonMigrate(serverDB, { migrationsFolder });
24
25
  }
25
26
 
26
- console.log('✅ database migration pass.');
27
+ console.log('✅ database migration pass. use: %s ms', Date.now() - time);
27
28
  // eslint-disable-next-line unicorn/no-process-exit
28
29
  process.exit(0);
29
30
  };
@@ -122,7 +122,6 @@ export async function POST(request: NextRequest) {
122
122
  }
123
123
 
124
124
  return NextResponse.redirect(finalRedirectUrl, {
125
- headers: request.headers,
126
125
  status: 303,
127
126
  });
128
127
  } catch (error) {
@@ -18,7 +18,7 @@ export const GET = async (request: NextRequest) => {
18
18
  return NextResponse.json('tag query parameter is required', { status: 400 });
19
19
  }
20
20
 
21
- revalidateTag(tag);
21
+ revalidateTag(tag, 'max');
22
22
 
23
23
  return Response.json({ now: Date.now(), revalidated: true });
24
24
  };
@@ -9,7 +9,7 @@ import { Flexbox } from 'react-layout-kit';
9
9
  import { ActionKeys } from '@/features/ChatInput/ActionBar/config';
10
10
  import { useInitAgentConfig } from '@/hooks/useInitAgentConfig';
11
11
  import { useChatStore } from '@/store/chat';
12
- import { chatSelectors } from '@/store/chat/selectors';
12
+ import { messageStateSelectors } from '@/store/chat/selectors';
13
13
 
14
14
  import ActionBar from './ActionBar';
15
15
  import Files from './Files';
@@ -37,7 +37,7 @@ const MobileChatInput = memo(() => {
37
37
  const { isLoading } = useInitAgentConfig();
38
38
 
39
39
  const [loading, value, onInput, onStop] = useChatStore((s) => [
40
- chatSelectors.isAIGenerating(s),
40
+ messageStateSelectors.isAIGenerating(s),
41
41
  s.inputMessage,
42
42
  s.updateInputMessage,
43
43
  s.stopGenerateMessage,
@@ -6,7 +6,7 @@ import { useGeminiChineseWarning } from '@/hooks/useGeminiChineseWarning';
6
6
  import { getAgentStoreState } from '@/store/agent';
7
7
  import { agentSelectors } from '@/store/agent/selectors';
8
8
  import { useChatStore } from '@/store/chat';
9
- import { chatSelectors, topicSelectors } from '@/store/chat/selectors';
9
+ import { chatSelectors, messageStateSelectors, topicSelectors } from '@/store/chat/selectors';
10
10
  import { fileChatSelectors, useFileStore } from '@/store/file';
11
11
  import { getUserStoreState } from '@/store/user';
12
12
 
@@ -26,17 +26,19 @@ export const useSendMessage = () => {
26
26
  const clearChatUploadFileList = useFileStore((s) => s.clearChatUploadFileList);
27
27
 
28
28
  const isUploadingFiles = useFileStore(fileChatSelectors.isUploadingFiles);
29
- const isSendButtonDisabledByMessage = useChatStore(chatSelectors.isSendButtonDisabledByMessage);
29
+ const isSendButtonDisabledByMessage = useChatStore(
30
+ messageStateSelectors.isSendButtonDisabledByMessage,
31
+ );
30
32
 
31
33
  const canSend = !isUploadingFiles && !isSendButtonDisabledByMessage;
32
34
 
33
35
  const send = useCallback(async (params: UseSendMessageParams = {}) => {
34
36
  const store = useChatStore.getState();
35
- if (chatSelectors.isAIGenerating(store)) return;
37
+ if (messageStateSelectors.isAIGenerating(store)) return;
36
38
 
37
39
  // if uploading file or send button is disabled by message, then we should not send the message
38
40
  const isUploadingFiles = fileChatSelectors.isUploadingFiles(useFileStore.getState());
39
- const isSendButtonDisabledByMessage = chatSelectors.isSendButtonDisabledByMessage(
41
+ const isSendButtonDisabledByMessage = messageStateSelectors.isSendButtonDisabledByMessage(
40
42
  useChatStore.getState(),
41
43
  );
42
44
 
@@ -5,7 +5,12 @@ import { useGeminiChineseWarning } from '@/hooks/useGeminiChineseWarning';
5
5
  import { getAgentStoreState } from '@/store/agent';
6
6
  import { agentSelectors } from '@/store/agent/selectors';
7
7
  import { getChatStoreState, useChatStore } from '@/store/chat';
8
- import { aiChatSelectors, chatSelectors, topicSelectors } from '@/store/chat/selectors';
8
+ import {
9
+ aiChatSelectors,
10
+ chatSelectors,
11
+ messageStateSelectors,
12
+ topicSelectors,
13
+ } from '@/store/chat/selectors';
9
14
  import { fileChatSelectors, useFileStore } from '@/store/file';
10
15
  import { mentionSelectors, useMentionStore } from '@/store/mention';
11
16
  import { useSessionStore } from '@/store/session';
@@ -38,8 +43,8 @@ export const useSend = () => {
38
43
  s.addAIMessage,
39
44
  s.stopGenerateMessage,
40
45
  s.cancelSendMessageInServer,
41
- chatSelectors.isAIGenerating(s),
42
- chatSelectors.isSendButtonDisabledByMessage(s),
46
+ messageStateSelectors.isAIGenerating(s),
47
+ messageStateSelectors.isSendButtonDisabledByMessage(s),
43
48
  aiChatSelectors.isCurrentSendMessageLoading(s),
44
49
  ]);
45
50
  const { analytics } = useAnalytics();
@@ -68,7 +73,7 @@ export const useSend = () => {
68
73
  return;
69
74
  }
70
75
 
71
- if (chatSelectors.isAIGenerating(store)) return;
76
+ if (messageStateSelectors.isAIGenerating(store)) return;
72
77
 
73
78
  const inputMessage = store.inputMessage;
74
79
  // 发送时再取一次最新的文件列表,防止闭包拿到旧值
@@ -127,7 +132,7 @@ export const useSend = () => {
127
132
 
128
133
  const stop = () => {
129
134
  const store = getChatStoreState();
130
- const generating = chatSelectors.isAIGenerating(store);
135
+ const generating = messageStateSelectors.isAIGenerating(store);
131
136
 
132
137
  if (generating) {
133
138
  stopGenerateMessage();
@@ -165,8 +170,8 @@ export const useSendGroupMessage = () => {
165
170
  s.sendGroupMessage,
166
171
  s.updateInputMessage,
167
172
  s.stopGenerateMessage,
168
- chatSelectors.isSendButtonDisabledByMessage(s),
169
- chatSelectors.isCreatingMessage(s),
173
+ messageStateSelectors.isSendButtonDisabledByMessage(s),
174
+ messageStateSelectors.isCreatingMessage(s),
170
175
  ]);
171
176
 
172
177
  const isSupervisorThinking = useChatStore((s) =>
@@ -205,7 +210,7 @@ export const useSendGroupMessage = () => {
205
210
 
206
211
  if (
207
212
  chatSelectors.isSupervisorLoading(store.activeId)(store) ||
208
- chatSelectors.isCreatingMessage(store)
213
+ messageStateSelectors.isCreatingMessage(store)
209
214
  )
210
215
  return;
211
216
 
@@ -287,8 +292,8 @@ export const useSendGroupMessage = () => {
287
292
 
288
293
  const stop = useCallback(() => {
289
294
  const store = getChatStoreState();
290
- const isAgentGenerating = chatSelectors.isAIGenerating(store);
291
- const isCreating = chatSelectors.isCreatingMessage(store);
295
+ const isAgentGenerating = messageStateSelectors.isAIGenerating(store);
296
+ const isCreating = messageStateSelectors.isCreatingMessage(store);
292
297
 
293
298
  if (isAgentGenerating) {
294
299
  stopGenerateMessage();
@@ -8,7 +8,7 @@ import { isDesktop } from '@/const/version';
8
8
  import { useAgentStore } from '@/store/agent';
9
9
  import { agentSelectors } from '@/store/agent/selectors';
10
10
  import { useChatStore } from '@/store/chat';
11
- import { chatSelectors } from '@/store/chat/selectors';
11
+ import { messageStateSelectors } from '@/store/chat/selectors';
12
12
  import { useGlobalStore } from '@/store/global';
13
13
  import { useSessionStore } from '@/store/session';
14
14
  import { sessionHelpers } from '@/store/session/helpers';
@@ -33,7 +33,9 @@ const SessionItem = memo<SessionItemProps>(({ id }) => {
33
33
  const openSessionInNewWindow = useGlobalStore((s) => s.openSessionInNewWindow);
34
34
 
35
35
  const [active] = useSessionStore((s) => [s.activeId === id]);
36
- const [loading] = useChatStore((s) => [chatSelectors.isAIGenerating(s) && id === s.activeId]);
36
+ const [loading] = useChatStore((s) => [
37
+ messageStateSelectors.isAIGenerating(s) && id === s.activeId,
38
+ ]);
37
39
 
38
40
  const [pin, title, avatar, avatarBackground, updateAt, members, model, group, sessionType] =
39
41
  useSessionStore((s) => {
@@ -15,9 +15,6 @@ const componentMap = {
15
15
  [SettingsTabs.Agent]: dynamic(() => import('../agent'), {
16
16
  loading: () => <Loading />,
17
17
  }),
18
- [SettingsTabs.LLM]: dynamic(() => import('../llm'), {
19
- loading: () => <Loading />,
20
- }),
21
18
  [SettingsTabs.Provider]: dynamic(() => import('../provider'), {
22
19
  loading: () => <Loading />,
23
20
  }),
@@ -73,6 +73,7 @@ export const generateViewport = async (props: DynamicLayoutProps): ResolvingView
73
73
 
74
74
  return {
75
75
  ...dynamicScale,
76
+ colorScheme: null,
76
77
  initialScale: 1,
77
78
  minimumScale: 1,
78
79
  themeColor: [
@@ -47,7 +47,13 @@ export function parsePaginatedId(id: string): { page?: number; type: SitemapType
47
47
  return { type: id as SitemapType };
48
48
  }
49
49
 
50
- export default async function sitemap({ id }: { id: string }): Promise<MetadataRoute.Sitemap> {
50
+ export default async function sitemap({
51
+ id: idPromise,
52
+ }: {
53
+ id: string;
54
+ }): Promise<MetadataRoute.Sitemap> {
55
+ const id = await idPromise;
56
+
51
57
  const { type, page } = parsePaginatedId(id);
52
58
  const sitemapModule = new Sitemap();
53
59
 
@@ -1,8 +1,8 @@
1
1
  import { ChatCitationItem } from '@lobechat/types';
2
- import { ActionIcon, CopyButton, Icon, Markdown, ScrollShadow } from '@lobehub/ui';
2
+ import { CopyButton, Icon, Markdown, ScrollShadow } from '@lobehub/ui';
3
3
  import { createStyles } from 'antd-style';
4
4
  import { AnimatePresence, motion } from 'framer-motion';
5
- import { AtomIcon, ChevronDown, ChevronRight } from 'lucide-react';
5
+ import { AtomIcon } from 'lucide-react';
6
6
  import { rgba } from 'polished';
7
7
  import { CSSProperties, RefObject, memo, useEffect, useRef, useState } from 'react';
8
8
  import { useTranslation } from 'react-i18next';
@@ -24,8 +24,10 @@ const useStyles = createStyles(({ css, token }) => ({
24
24
  color: ${token.colorTextTertiary};
25
25
  `,
26
26
  header: css`
27
+ min-height: 32px;
27
28
  padding-block: 4px;
28
29
  padding-inline: 8px 4px;
30
+
29
31
  transition: background 0.2s ${token.motionEaseOut};
30
32
  transition: all 0.2s ${token.motionEaseOut};
31
33
 
@@ -165,7 +167,6 @@ const Thinking = memo<ThinkingProps>((props) => {
165
167
  <CopyButton content={content} size={'small'} title={t('copy', { ns: 'common' })} />
166
168
  </div>
167
169
  )}
168
- <ActionIcon icon={showDetail ? ChevronDown : ChevronRight} size={'small'} />
169
170
  </Flexbox>
170
171
  </Flexbox>
171
172
  <AnimatePresence initial={false}>
@@ -48,29 +48,6 @@ const Anthropic: ModelProviderCard = {
48
48
  maxOutput: 8192,
49
49
  releasedAt: '2024-11-05',
50
50
  },
51
- {
52
- contextWindowTokens: 200_000,
53
- description:
54
- 'Claude 3.5 Sonnet 提供了超越 Opus 的能力和比 Sonnet 更快的速度,同时保持与 Sonnet 相同的价格。Sonnet 特别擅长编程、数据科学、视觉处理、代理任务。',
55
- displayName: 'Claude 3.5 Sonnet',
56
- enabled: true,
57
- functionCall: true,
58
- id: 'claude-3-5-sonnet-20241022',
59
- maxOutput: 8192,
60
- releasedAt: '2024-10-22',
61
- vision: true,
62
- },
63
- {
64
- contextWindowTokens: 200_000,
65
- description:
66
- 'Claude 3.5 Sonnet 提供了超越 Opus 的能力和比 Sonnet 更快的速度,同时保持与 Sonnet 相同的价格。Sonnet 特别擅长编程、数据科学、视觉处理、代理任务。',
67
- displayName: 'Claude 3.5 Sonnet 0620',
68
- functionCall: true,
69
- id: 'claude-3-5-sonnet-20240620',
70
- maxOutput: 8192,
71
- releasedAt: '2024-06-20',
72
- vision: true,
73
- },
74
51
  {
75
52
  contextWindowTokens: 200_000,
76
53
  description:
@@ -1298,29 +1298,6 @@ const Higress: ModelProviderCard = {
1298
1298
  maxOutput: 8192,
1299
1299
  releasedAt: '2024-11-05',
1300
1300
  },
1301
- {
1302
- contextWindowTokens: 200_000,
1303
- description:
1304
- 'Claude 3.5 Sonnet 提供了超越 Opus 的能力和比 Sonnet 更快的速度,同时保持与 Sonnet 相同的价格。Sonnet 特别擅长编程、数据科学、视觉处理、代理任务。',
1305
- displayName: 'Claude 3.5 Sonnet',
1306
- enabled: true,
1307
- functionCall: true,
1308
- id: 'claude-3-5-sonnet-20241022',
1309
- maxOutput: 8192,
1310
- releasedAt: '2024-10-22',
1311
- vision: true,
1312
- },
1313
- {
1314
- contextWindowTokens: 200_000,
1315
- description:
1316
- 'Claude 3.5 Sonnet 提供了超越 Opus 的能力和比 Sonnet 更快的速度,同时保持与 Sonnet 相同的价格。Sonnet 特别擅长编程、数据科学、视觉处理、代理任务。',
1317
- displayName: 'Claude 3.5 Sonnet 0620',
1318
- functionCall: true,
1319
- id: 'claude-3-5-sonnet-20240620',
1320
- maxOutput: 8192,
1321
- releasedAt: '2024-06-20',
1322
- vision: true,
1323
- },
1324
1301
  {
1325
1302
  contextWindowTokens: 200_000,
1326
1303
  description:
@@ -12,7 +12,7 @@ const Minimax: ModelProviderCard = {
12
12
  settings: {
13
13
  disableBrowserRequest: true, // CORS error
14
14
  proxyUrl: {
15
- placeholder: 'https://api.minimax.chat/v1',
15
+ placeholder: 'https://api.minimaxi.com/v1',
16
16
  },
17
17
  responseAnimation: {
18
18
  speed: 2,
@@ -28,7 +28,7 @@ const Qiniu: ModelProviderCard = {
28
28
  name: 'Qiniu',
29
29
  settings: {
30
30
  proxyUrl: {
31
- placeholder: 'https://api.qnaigc.com/v1',
31
+ placeholder: 'https://openai.qiniu.com/v1',
32
32
  },
33
33
  sdkType: 'openai',
34
34
  showModelFetcher: true,