@lobehub/lobehub 2.1.7 → 2.1.9

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 CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 2.1.9](https://github.com/lobehub/lobe-chat/compare/v2.1.8...v2.1.9)
6
+
7
+ <sup>Released on **2026-02-02**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Use oauth2.link for generic OIDC provider account linking.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Use oauth2.link for generic OIDC provider account linking, closes [#12024](https://github.com/lobehub/lobe-chat/issues/12024) ([c7a06a4](https://github.com/lobehub/lobe-chat/commit/c7a06a4))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
30
+ ### [Version 2.1.8](https://github.com/lobehub/lobe-chat/compare/v2.1.7...v2.1.8)
31
+
32
+ <sup>Released on **2026-02-01**</sup>
33
+
34
+ #### 💄 Styles
35
+
36
+ - **misc**: Improve tasks display.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### Styles
44
+
45
+ - **misc**: Improve tasks display, closes [#12032](https://github.com/lobehub/lobe-chat/issues/12032) ([3423ad1](https://github.com/lobehub/lobe-chat/commit/3423ad1))
46
+
47
+ </details>
48
+
49
+ <div align="right">
50
+
51
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
52
+
53
+ </div>
54
+
5
55
  ### [Version 2.1.7](https://github.com/lobehub/lobe-chat/compare/v2.1.6...v2.1.7)
6
56
 
7
57
  <sup>Released on **2026-02-01**</sup>
package/changelog/v2.json CHANGED
@@ -1,4 +1,22 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "fixes": [
5
+ "Use oauth2.link for generic OIDC provider account linking."
6
+ ]
7
+ },
8
+ "date": "2026-02-02",
9
+ "version": "2.1.9"
10
+ },
11
+ {
12
+ "children": {
13
+ "improvements": [
14
+ "Improve tasks display."
15
+ ]
16
+ },
17
+ "date": "2026-02-01",
18
+ "version": "2.1.8"
19
+ },
2
20
  {
3
21
  "children": {
4
22
  "fixes": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.1.7",
3
+ "version": "2.1.9",
4
4
  "description": "LobeHub - an open-source,comprehensive AI Agent 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",
@@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next';
6
6
 
7
7
  import { modal, notification } from '@/components/AntdStaticMethods';
8
8
  import AuthIcons from '@/components/AuthIcons';
9
+ import { isBuiltinProvider, normalizeProviderId } from '@/libs/better-auth/utils/client';
9
10
  import { useServerConfigStore } from '@/store/serverConfig';
10
11
  import { serverConfigSelectors } from '@/store/serverConfig/selectors';
11
12
  import { useUserStore } from '@/store/user';
@@ -33,8 +34,11 @@ export const SSOProvidersList = memo(() => {
33
34
  }, [providers]);
34
35
 
35
36
  // Get available providers for linking (filter out already linked)
37
+ // Normalize provider IDs when comparing to handle aliases (e.g. microsoft-entra-id → microsoft)
36
38
  const availableProviders = useMemo(() => {
37
- return (oAuthSSOProviders || []).filter((provider) => !linkedProviderIds.has(provider));
39
+ return (oAuthSSOProviders || []).filter(
40
+ (provider) => !linkedProviderIds.has(normalizeProviderId(provider)),
41
+ );
38
42
  }, [oAuthSSOProviders, linkedProviderIds]);
39
43
 
40
44
  const handleUnlinkSSO = async (provider: string) => {
@@ -63,14 +67,24 @@ export const SSOProvidersList = memo(() => {
63
67
  };
64
68
 
65
69
  const handleLinkSSO = async (provider: string) => {
66
- if (enableAuthActions) {
67
- // Use better-auth native linkSocial API
68
- const { linkSocial } = await import('@/libs/better-auth/auth-client');
70
+ if (!enableAuthActions) return;
71
+
72
+ const normalizedProvider = normalizeProviderId(provider);
73
+ const { linkSocial, oauth2 } = await import('@/libs/better-auth/auth-client');
74
+
75
+ if (isBuiltinProvider(normalizedProvider)) {
76
+ // Use better-auth native linkSocial API for built-in providers
69
77
  await linkSocial({
70
78
  callbackURL: '/profile',
71
- provider: provider as any,
79
+ provider: normalizedProvider as any,
72
80
  });
81
+ return;
73
82
  }
83
+
84
+ await oauth2.link({
85
+ callbackURL: '/profile',
86
+ providerId: normalizedProvider,
87
+ });
74
88
  };
75
89
 
76
90
  // Dropdown menu items for linking new providers
@@ -20,10 +20,12 @@ export const styles = createStaticStyles(({ css, cssVar }) => ({
20
20
  `,
21
21
  paramKey: css`
22
22
  font-family: ${cssVar.fontFamilyCode};
23
+ font-size: 12px;
23
24
  color: ${cssVar.colorTextTertiary};
24
25
  `,
25
26
  paramValue: css`
26
27
  font-family: ${cssVar.fontFamilyCode};
28
+ font-size: 12px;
27
29
  color: ${cssVar.colorTextSecondary};
28
30
  `,
29
31
  root: css`
@@ -327,11 +327,37 @@ const TaskMessages = memo<TaskMessagesProps>(
327
327
  const assistantGroupMessage = messages.find((item) => item.role === 'assistantGroup');
328
328
  const userMessage = messages.find((item) => item.role === 'user');
329
329
 
330
- return {
331
- assistantId: assistantGroupMessage?.id ?? '',
332
- blocks: assistantGroupMessage?.children ?? [],
333
- instruction: userMessage?.content,
334
- };
330
+ // If assistantGroup exists, use its children as blocks
331
+ if (assistantGroupMessage) {
332
+ return {
333
+ assistantId: assistantGroupMessage.id ?? '',
334
+ blocks: assistantGroupMessage.children ?? [],
335
+ instruction: userMessage?.content,
336
+ };
337
+ }
338
+
339
+ // Fallback: support plain assistant message (without tools)
340
+ // This handles cases where SubAgent returns a simple text response
341
+ const assistantMessage = messages.find((item) => item.role === 'assistant');
342
+ if (assistantMessage) {
343
+ // Convert plain assistant message to block format
344
+ const block: AssistantContentBlock = {
345
+ content: assistantMessage.content || '',
346
+ id: assistantMessage.id,
347
+ };
348
+
349
+ // Copy optional fields if they exist
350
+ if (assistantMessage.error) block.error = assistantMessage.error;
351
+ if (assistantMessage.reasoning) block.reasoning = assistantMessage.reasoning;
352
+
353
+ return {
354
+ assistantId: assistantMessage.id ?? '',
355
+ blocks: [block],
356
+ instruction: userMessage?.content,
357
+ };
358
+ }
359
+
360
+ return { assistantId: '', blocks: [], instruction: undefined };
335
361
  }, [messages]);
336
362
 
337
363
  // Calculate total tool calls
@@ -12,7 +12,7 @@ export const useFetchAgentList = () => {
12
12
 
13
13
  const { isValidating, data } = useFetchAgentListHook(isLogin);
14
14
 
15
- // isRevalidating: 有缓存数据,后台正在更新
15
+ // isRevalidating: has cached data, updating in background
16
16
  return {
17
17
  isRevalidating: isValidating && !!data,
18
18
  };
@@ -49,7 +49,7 @@ export const useClearCurrentMessagesHotkey = () => {
49
49
  });
50
50
  };
51
51
 
52
- // 注册聚合
52
+ // Register aggregate
53
53
 
54
54
  export const useRegisterChatHotkeys = () => {
55
55
  const { enableScope, disableScope } = useHotkeysContext();
@@ -7,7 +7,7 @@ import { useGlobalStore } from '@/store/global';
7
7
 
8
8
  import { useHotkeyById } from './useHotkeyById';
9
9
 
10
- // 切换到会话标签(并聚焦到Lobe AI)
10
+ // Switch to chat tab (and focus on Lobe AI)
11
11
  export const useNavigateToChatHotkey = () => {
12
12
  const navigateToAgent = useNavigateToAgent();
13
13
  const [, { unpinAgent }] = usePinnedAgentState();
@@ -58,7 +58,7 @@ export const useCommandPaletteHotkey = () => {
58
58
  };
59
59
 
60
60
  export const useRegisterGlobalHotkeys = () => {
61
- // 全局自动注册不需要 enableScope
61
+ // Global auto-registration doesn't need enableScope
62
62
  useToggleLeftPanelHotkey();
63
63
  useToggleRightPanelHotkey();
64
64
  useNavigateToChatHotkey();
@@ -19,7 +19,7 @@ export const useToggleImageRightPanelHotkey = () => {
19
19
  );
20
20
  };
21
21
 
22
- // 注册聚合
22
+ // Register aggregate
23
23
 
24
24
  export const useRegisterImageHotkeys = () => {
25
25
  const { enableScope, disableScope } = useHotkeysContext();
@@ -19,7 +19,7 @@ export const usePWAInstall = () => {
19
19
  }, []);
20
20
 
21
21
  const installCheck = () => {
22
- // 当在 PWA 或不支持 PWA 的环境中时,不显示安装按钮
22
+ // Don't show install button when in PWA or environment that doesn't support PWA
23
23
  if (isPWA || !isSupportInstallPWA) return false;
24
24
  const pwa: any = document.querySelector(`#${PWA_INSTALL_ID}`);
25
25
  if (!pwa) return false;
@@ -10,6 +10,7 @@ import type { auth } from '@/auth';
10
10
 
11
11
  export const {
12
12
  linkSocial,
13
+ oauth2,
13
14
  accountInfo,
14
15
  listAccounts,
15
16
  requestPasswordReset,