@lobehub/chat 1.69.4 → 1.69.6

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 (65) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/changelog/v1.json +18 -0
  3. package/docker-compose/setup.sh +92 -1
  4. package/docs/self-hosting/advanced/auth/clerk.mdx +1 -0
  5. package/locales/ar/components.json +2 -0
  6. package/locales/ar/models.json +3 -0
  7. package/locales/bg-BG/components.json +2 -0
  8. package/locales/bg-BG/models.json +3 -0
  9. package/locales/de-DE/components.json +2 -0
  10. package/locales/de-DE/models.json +3 -0
  11. package/locales/en-US/components.json +2 -0
  12. package/locales/en-US/models.json +3 -0
  13. package/locales/es-ES/components.json +2 -0
  14. package/locales/es-ES/models.json +3 -0
  15. package/locales/fa-IR/components.json +2 -0
  16. package/locales/fa-IR/models.json +3 -0
  17. package/locales/fr-FR/components.json +2 -0
  18. package/locales/fr-FR/models.json +3 -0
  19. package/locales/it-IT/components.json +2 -0
  20. package/locales/it-IT/models.json +3 -0
  21. package/locales/ja-JP/components.json +2 -0
  22. package/locales/ja-JP/models.json +3 -0
  23. package/locales/ko-KR/components.json +2 -0
  24. package/locales/ko-KR/models.json +3 -0
  25. package/locales/nl-NL/components.json +2 -0
  26. package/locales/nl-NL/models.json +3 -0
  27. package/locales/pl-PL/components.json +2 -0
  28. package/locales/pl-PL/models.json +3 -0
  29. package/locales/pt-BR/components.json +2 -0
  30. package/locales/pt-BR/models.json +3 -0
  31. package/locales/ru-RU/components.json +2 -0
  32. package/locales/ru-RU/models.json +3 -0
  33. package/locales/tr-TR/components.json +2 -0
  34. package/locales/tr-TR/models.json +3 -0
  35. package/locales/vi-VN/components.json +2 -0
  36. package/locales/vi-VN/models.json +3 -0
  37. package/locales/zh-CN/components.json +3 -1
  38. package/locales/zh-CN/models.json +3 -0
  39. package/locales/zh-TW/components.json +2 -0
  40. package/locales/zh-TW/models.json +3 -0
  41. package/package.json +4 -4
  42. package/packages/web-crawler/package.json +1 -1
  43. package/packages/web-crawler/src/crawImpl/__tests__/browserless.test.ts +94 -0
  44. package/packages/web-crawler/src/crawImpl/browserless.ts +1 -1
  45. package/packages/web-crawler/src/crawImpl/naive.ts +1 -1
  46. package/packages/web-crawler/src/utils/__snapshots__/htmlToMarkdown.test.ts.snap +2 -382
  47. package/packages/web-crawler/src/utils/htmlToMarkdown.ts +32 -2
  48. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/Footer/MessageFromUrl.tsx +31 -0
  49. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/Footer/index.tsx +45 -39
  50. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/InboxWelcome/AgentsSuggest.tsx +5 -1
  51. package/src/config/aiModels/openrouter.ts +26 -1
  52. package/src/config/modelProviders/openai.ts +3 -0
  53. package/src/database/client/db.ts +3 -3
  54. package/src/features/Conversation/components/MarkdownElements/LobeArtifact/Render/index.tsx +51 -52
  55. package/src/features/ModelSwitchPanel/index.tsx +37 -8
  56. package/src/libs/agent-runtime/anthropic/index.ts +5 -2
  57. package/src/libs/agent-runtime/openrouter/index.test.ts +33 -0
  58. package/src/libs/agent-runtime/openrouter/index.ts +11 -2
  59. package/src/libs/agent-runtime/openrouter/type.ts +19 -0
  60. package/src/locales/default/components.ts +3 -1
  61. package/src/services/__tests__/chat.test.ts +123 -0
  62. package/src/services/chat.ts +19 -19
  63. package/src/store/user/slices/modelList/action.ts +17 -16
  64. package/src/utils/fetch/__tests__/fetchSSE.test.ts +3 -2
  65. package/src/utils/fetch/fetchSSE.ts +1 -1
@@ -19,12 +19,7 @@ import { filesPrompts } from '@/prompts/files';
19
19
  import { BuiltinSystemRolePrompts } from '@/prompts/systemRole';
20
20
  import { getAgentStoreState } from '@/store/agent';
21
21
  import { agentChatConfigSelectors } from '@/store/agent/selectors';
22
- import {
23
- aiModelSelectors,
24
- aiProviderSelectors,
25
- getAiInfraStoreState,
26
- useAiInfraStore,
27
- } from '@/store/aiInfra';
22
+ import { aiModelSelectors, aiProviderSelectors, getAiInfraStoreState } from '@/store/aiInfra';
28
23
  import { getSessionStoreState } from '@/store/session';
29
24
  import { sessionMetaSelectors } from '@/store/session/selectors';
30
25
  import { getToolStoreState } from '@/store/tool';
@@ -74,9 +69,9 @@ const findDeploymentName = (model: string, provider: string) => {
74
69
  if (deploymentName) deploymentId = deploymentName;
75
70
  } else {
76
71
  // find the model by id
77
- const modelItem = useAiInfraStore
78
- .getState()
79
- .enabledAiModels?.find((i) => i.id === model && i.providerId === provider);
72
+ const modelItem = getAiInfraStoreState().enabledAiModels?.find(
73
+ (i) => i.id === model && i.providerId === provider,
74
+ );
80
75
 
81
76
  if (modelItem && modelItem.config?.deploymentName) {
82
77
  deploymentId = modelItem.config?.deploymentName;
@@ -91,7 +86,7 @@ const isEnableFetchOnClient = (provider: string) => {
91
86
  if (isDeprecatedEdition) {
92
87
  return modelConfigSelectors.isProviderFetchOnClient(provider)(useUserStore.getState());
93
88
  } else {
94
- return aiProviderSelectors.isProviderFetchOnClient(provider)(useAiInfraStore.getState());
89
+ return aiProviderSelectors.isProviderFetchOnClient(provider)(getAiInfraStoreState());
95
90
  }
96
91
  };
97
92
 
@@ -181,10 +176,10 @@ class ChatService {
181
176
  const isModelHasBuiltinSearch = aiModelSelectors.isModelHasBuiltinSearch(
182
177
  payload.model,
183
178
  payload.provider!,
184
- )(useAiInfraStore.getState());
179
+ )(getAiInfraStoreState());
185
180
 
186
- const useApplicationBuiltinSearchTool =
187
- enabledSearch && !(isModelHasBuiltinSearch && chatConfig.useModelBuiltinSearch);
181
+ const useModelSearch = isModelHasBuiltinSearch && chatConfig.useModelBuiltinSearch;
182
+ const useApplicationBuiltinSearchTool = enabledSearch && !useModelSearch;
188
183
 
189
184
  const pluginIds = [...(enabledPlugins || [])];
190
185
 
@@ -225,14 +220,14 @@ class ChatService {
225
220
  const isModelHasExtendParams = aiModelSelectors.isModelHasExtendParams(
226
221
  payload.model,
227
222
  payload.provider!,
228
- )(useAiInfraStore.getState());
223
+ )(getAiInfraStoreState());
229
224
 
230
225
  // model
231
226
  if (isModelHasExtendParams) {
232
227
  const modelExtendParams = aiModelSelectors.modelExtendParams(
233
228
  payload.model,
234
229
  payload.provider!,
235
- )(useAiInfraStore.getState());
230
+ )(getAiInfraStoreState());
236
231
  // if model has extended params, then we need to check if the model can use reasoning
237
232
 
238
233
  if (modelExtendParams!.includes('enableReasoning') && chatConfig.enableReasoning) {
@@ -241,13 +236,19 @@ class ChatService {
241
236
  type: 'enabled',
242
237
  };
243
238
  }
239
+ if (
240
+ modelExtendParams!.includes('disableContextCaching') &&
241
+ chatConfig.disableContextCaching
242
+ ) {
243
+ extendParams.enabledContextCaching = false;
244
+ }
244
245
  }
245
246
 
246
247
  return this.getChatCompletion(
247
248
  {
248
249
  ...params,
249
250
  ...extendParams,
250
- enabledSearch: enabledSearch && isModelHasBuiltinSearch ? true : undefined,
251
+ enabledSearch: enabledSearch && useModelSearch ? true : undefined,
251
252
  messages: oaiMessages,
252
253
  tools,
253
254
  },
@@ -351,9 +352,8 @@ class ChatService {
351
352
 
352
353
  // TODO: remove `!isDeprecatedEdition` condition in V2.0
353
354
  if (!isDeprecatedEdition && !isBuiltin) {
354
- const providerConfig = aiProviderSelectors.providerConfigById(provider)(
355
- useAiInfraStore.getState(),
356
- );
355
+ const providerConfig =
356
+ aiProviderSelectors.providerConfigById(provider)(getAiInfraStoreState());
357
357
 
358
358
  sdkType = providerConfig?.settings.sdkType || 'openai';
359
359
  }
@@ -118,22 +118,23 @@ export const createModelListSlice: StateCreator<
118
118
  get().refreshModelProviderList({ trigger: 'refreshDefaultModelList' });
119
119
  },
120
120
  refreshModelProviderList: (params) => {
121
- const modelProviderList = get().defaultModelProviderList.map((list) => ({
122
- ...list,
123
- chatModels: modelProviderSelectors
124
- .getModelCardsById(list.id)(get())
125
- ?.map((model) => {
126
- const models = modelProviderSelectors.getEnableModelsById(list.id)(get());
127
-
128
- if (!models) return model;
129
-
130
- return {
131
- ...model,
132
- enabled: models?.some((m) => m === model.id),
133
- };
134
- }),
135
- enabled: modelProviderSelectors.isProviderEnabled(list.id as any)(get()),
136
- }));
121
+ const modelProviderList = get().defaultModelProviderList.map((list) => {
122
+ const enabledModels = modelProviderSelectors.getEnableModelsById(list.id)(get());
123
+ return {
124
+ ...list,
125
+ chatModels: modelProviderSelectors
126
+ .getModelCardsById(list.id)(get())
127
+ ?.map((model) => {
128
+ if (!enabledModels) return model;
129
+
130
+ return {
131
+ ...model,
132
+ enabled: enabledModels?.some((m) => m === model.id),
133
+ };
134
+ }),
135
+ enabled: modelProviderSelectors.isProviderEnabled(list.id as any)(get()),
136
+ };
137
+ });
137
138
 
138
139
  set({ modelProviderList }, false, `refreshModelList - ${params?.trigger}`);
139
140
  },
@@ -159,7 +159,7 @@ describe('fetchSSE', () => {
159
159
  expectedMessages.forEach((message, index) => {
160
160
  expect(mockOnMessageHandle).toHaveBeenNthCalledWith(index + 1, message);
161
161
  });
162
-
162
+
163
163
  // more assertions for each character...
164
164
  expect(mockOnFinish).toHaveBeenCalledWith('Hello World', {
165
165
  observationId: null,
@@ -188,6 +188,7 @@ describe('fetchSSE', () => {
188
188
  await fetchSSE('/', {
189
189
  onMessageHandle: mockOnMessageHandle,
190
190
  onFinish: mockOnFinish,
191
+ smoothing: false,
191
192
  });
192
193
 
193
194
  expect(mockOnMessageHandle).toHaveBeenNthCalledWith(1, { text: 'Hello', type: 'reasoning' });
@@ -225,7 +226,7 @@ describe('fetchSSE', () => {
225
226
  grounding: 'Hello',
226
227
  type: 'grounding',
227
228
  });
228
-
229
+
229
230
  expect(mockOnFinish).toHaveBeenCalledWith('hi', {
230
231
  observationId: null,
231
232
  toolCalls: undefined,
@@ -296,7 +296,7 @@ export const fetchSSE = async (url: string, options: RequestInit & FetchSSEOptio
296
296
 
297
297
  const { smoothing } = options;
298
298
 
299
- const textSmoothing = typeof smoothing === 'boolean' ? smoothing : smoothing?.text;
299
+ const textSmoothing = typeof smoothing === 'boolean' ? smoothing : (smoothing?.text ?? true);
300
300
  const toolsCallingSmoothing =
301
301
  typeof smoothing === 'boolean' ? smoothing : (smoothing?.toolsCalling ?? true);
302
302
  const smoothingSpeed = isObject(smoothing) ? smoothing.speed : undefined;