@lobehub/chat 1.74.10 → 1.75.0

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 (47) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/Dockerfile +2 -0
  3. package/Dockerfile.database +2 -0
  4. package/Dockerfile.pglite +2 -0
  5. package/changelog/v1.json +21 -0
  6. package/locales/ar/models.json +9 -0
  7. package/locales/bg-BG/models.json +9 -0
  8. package/locales/de-DE/models.json +9 -0
  9. package/locales/en-US/models.json +9 -0
  10. package/locales/es-ES/models.json +9 -0
  11. package/locales/fa-IR/models.json +9 -0
  12. package/locales/fr-FR/models.json +9 -0
  13. package/locales/it-IT/models.json +9 -0
  14. package/locales/ja-JP/models.json +9 -0
  15. package/locales/ko-KR/models.json +9 -0
  16. package/locales/nl-NL/models.json +9 -0
  17. package/locales/pl-PL/models.json +9 -0
  18. package/locales/pt-BR/models.json +9 -0
  19. package/locales/ru-RU/models.json +9 -0
  20. package/locales/tr-TR/models.json +9 -0
  21. package/locales/vi-VN/models.json +9 -0
  22. package/locales/zh-CN/models.json +9 -0
  23. package/locales/zh-TW/models.json +9 -0
  24. package/package.json +1 -1
  25. package/packages/web-crawler/src/crawImpl/__tests__/browserless.test.ts +41 -0
  26. package/packages/web-crawler/src/crawImpl/search1api.ts +2 -2
  27. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/index.tsx +1 -1
  28. package/src/app/[variants]/(main)/settings/_layout/Desktop/Header.tsx +11 -9
  29. package/src/app/[variants]/(main)/settings/llm/ProviderList/providers.tsx +2 -0
  30. package/src/config/aiModels/google.ts +26 -0
  31. package/src/config/aiModels/index.ts +3 -0
  32. package/src/config/aiModels/xinference.ts +171 -0
  33. package/src/config/llm.ts +6 -0
  34. package/src/config/modelProviders/index.ts +4 -0
  35. package/src/config/modelProviders/xinference.ts +18 -0
  36. package/src/features/Conversation/components/AutoScroll.tsx +2 -1
  37. package/src/features/Conversation/components/ChatItem/ActionsBar.tsx +7 -2
  38. package/src/features/Conversation/components/ChatItem/index.tsx +6 -1
  39. package/src/features/Conversation/components/VirtualizedList/VirtuosoContext.ts +4 -0
  40. package/src/features/Conversation/components/VirtualizedList/index.tsx +34 -31
  41. package/src/features/Portal/Thread/Chat/ChatItem.tsx +1 -1
  42. package/src/libs/agent-runtime/runtimeMap.ts +2 -0
  43. package/src/libs/agent-runtime/types/type.ts +1 -0
  44. package/src/libs/agent-runtime/xinference/index.ts +53 -0
  45. package/src/store/chat/slices/message/selectors.test.ts +42 -0
  46. package/src/store/chat/slices/message/selectors.ts +4 -0
  47. package/src/types/user/settings/keyVaults.ts +1 -0
@@ -0,0 +1,53 @@
1
+ import { ModelProvider } from '../types';
2
+ import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
3
+
4
+ import type { ChatModelCard } from '@/types/llm';
5
+
6
+ export interface XinferenceModelCard {
7
+ context_length: number;
8
+ id: string;
9
+ model_ability: string[];
10
+ model_description: string;
11
+ model_type: string;
12
+ name: string;
13
+ }
14
+
15
+ export const LobeXinferenceAI = LobeOpenAICompatibleFactory({
16
+ baseURL: 'http://localhost:9997/v1',
17
+ debug: {
18
+ chatCompletion: () => process.env.DEBUG_XINFERENCE_CHAT_COMPLETION === '1',
19
+ },
20
+ models: async ({ client }) => {
21
+ const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels');
22
+
23
+ const modelsPage = await client.models.list() as any;
24
+ const modelList: XinferenceModelCard[] = modelsPage.data;
25
+
26
+ return modelList
27
+ .map((model) => {
28
+ const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase());
29
+
30
+ return {
31
+ contextWindowTokens: model.context_length,
32
+ description: model.model_description,
33
+ displayName: model.name,
34
+ enabled: knownModel?.enabled || false,
35
+ functionCall:
36
+ (model.model_ability && model.model_ability.includes("tools"))
37
+ || knownModel?.abilities?.functionCall
38
+ || false,
39
+ id: model.id,
40
+ reasoning:
41
+ (model.model_ability && model.model_ability.includes("reasoning"))
42
+ || knownModel?.abilities?.reasoning
43
+ || false,
44
+ vision:
45
+ (model.model_ability && model.model_ability.includes("vision"))
46
+ || knownModel?.abilities?.vision
47
+ || false,
48
+ };
49
+ })
50
+ .filter(Boolean) as ChatModelCard[];
51
+ },
52
+ provider: ModelProvider.Xinference,
53
+ });
@@ -48,6 +48,27 @@ const mockMessages = [
48
48
  },
49
49
  ] as ChatMessage[];
50
50
 
51
+ const mockReasoningMessages = [
52
+ {
53
+ id: 'msg1',
54
+ content: 'Hello World',
55
+ role: 'user',
56
+ },
57
+ {
58
+ id: 'msg2',
59
+ content: 'Goodbye World',
60
+ role: 'user',
61
+ },
62
+ {
63
+ id: 'msg3',
64
+ content: 'Content Message',
65
+ role: 'assistant',
66
+ reasoning: {
67
+ content: 'Reasoning Content',
68
+ },
69
+ },
70
+ ] as ChatMessage[];
71
+
51
72
  const mockedChats = [
52
73
  {
53
74
  id: 'msg1',
@@ -270,6 +291,27 @@ describe('chatSelectors', () => {
270
291
  });
271
292
  });
272
293
 
294
+ describe('latestMessageReasoningContent', () => {
295
+ it('should return the reasoning content of the latest message', () => {
296
+ // Prepare a state with a few messages
297
+ const state = merge(initialStore, {
298
+ messagesMap: {
299
+ [messageMapKey('active-session')]: mockReasoningMessages,
300
+ },
301
+ activeId: 'active-session',
302
+ });
303
+
304
+ const expectedString = mockReasoningMessages.at(-1)?.reasoning?.content;
305
+
306
+ // Call the selector and verify the result
307
+ const reasoningContent = chatSelectors.mainAILatestMessageReasoningContent(state);
308
+ expect(reasoningContent).toBe(expectedString);
309
+
310
+ // Restore the mocks after the test
311
+ vi.restoreAllMocks();
312
+ });
313
+ });
314
+
273
315
  describe('showInboxWelcome', () => {
274
316
  it('should return false if the active session is not the inbox session', () => {
275
317
  const state = merge(initialStore, { activeId: 'someActiveId' });
@@ -98,6 +98,9 @@ const mainAIChatsMessageString = (s: ChatStoreState): string => {
98
98
  return chats.map((m) => m.content).join('');
99
99
  };
100
100
 
101
+ const mainAILatestMessageReasoningContent = (s: ChatStoreState) =>
102
+ mainAIChats(s).at(-1)?.reasoning?.content;
103
+
101
104
  const currentToolMessages = (s: ChatStoreState) => {
102
105
  const messages = activeBaseChats(s);
103
106
 
@@ -214,6 +217,7 @@ export const chatSelectors = {
214
217
  mainAIChats,
215
218
  mainAIChatsMessageString,
216
219
  mainAIChatsWithHistoryConfig,
220
+ mainAILatestMessageReasoningContent,
217
221
  mainDisplayChatIDs,
218
222
  mainDisplayChats,
219
223
  showInboxWelcome,
@@ -84,6 +84,7 @@ export interface UserKeyVaults extends SearchEngineKeyVaults {
84
84
  volcengine?: OpenAICompatibleKeyVault;
85
85
  wenxin?: OpenAICompatibleKeyVault;
86
86
  xai?: OpenAICompatibleKeyVault;
87
+ xinference?: OpenAICompatibleKeyVault;
87
88
  zeroone?: OpenAICompatibleKeyVault;
88
89
  zhipu?: OpenAICompatibleKeyVault;
89
90
  }