@lobehub/chat 1.139.1 → 1.139.3

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 (34) hide show
  1. package/.github/ISSUE_TEMPLATE/1_bug_report.yml +63 -19
  2. package/CHANGELOG.md +50 -0
  3. package/apps/desktop/package.json +1 -1
  4. package/changelog/v1.json +18 -0
  5. package/locales/ar/chat.json +3 -1
  6. package/locales/bg-BG/chat.json +3 -1
  7. package/locales/de-DE/chat.json +3 -1
  8. package/locales/en-US/chat.json +3 -1
  9. package/locales/es-ES/chat.json +3 -1
  10. package/locales/fa-IR/chat.json +3 -1
  11. package/locales/fr-FR/chat.json +3 -1
  12. package/locales/it-IT/chat.json +3 -1
  13. package/locales/ja-JP/chat.json +3 -1
  14. package/locales/ko-KR/chat.json +4 -2
  15. package/locales/nl-NL/chat.json +3 -1
  16. package/locales/pl-PL/chat.json +3 -1
  17. package/locales/pt-BR/chat.json +3 -1
  18. package/locales/ru-RU/chat.json +3 -1
  19. package/locales/tr-TR/chat.json +3 -1
  20. package/locales/vi-VN/chat.json +3 -1
  21. package/locales/zh-CN/chat.json +3 -1
  22. package/locales/zh-TW/chat.json +3 -1
  23. package/package.json +3 -3
  24. package/packages/model-runtime/package.json +1 -0
  25. package/packages/obervability-otel/package.json +2 -2
  26. package/src/app/[variants]/(main)/_layout/Desktop/SideBar/index.tsx +11 -7
  27. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatMinimap/index.tsx +28 -9
  28. package/src/layout/GlobalProvider/StoreInitialization.tsx +4 -1
  29. package/src/libs/swr/index.ts +13 -0
  30. package/src/libs/trpc/client/lambda.ts +13 -3
  31. package/src/locales/default/chat.ts +2 -0
  32. package/src/store/agent/slices/chat/action.ts +4 -2
  33. package/src/store/aiInfra/slices/aiProvider/action.ts +5 -3
  34. package/src/store/chat/slices/message/action.ts +0 -4
@@ -5,10 +5,38 @@ type: Bug
5
5
  body:
6
6
  - type: dropdown
7
7
  attributes:
8
- label: '📦 Platform'
8
+ label: '📱 Client Type'
9
+ description: 'Select how you are accessing LobeChat'
10
+ multiple: true
11
+ options:
12
+ - 'Web (Desktop Browser)'
13
+ - 'Web (Mobile Browser)'
14
+ - 'Desktop App (Electron)'
15
+ - 'Mobile App (React Native)'
16
+ - 'Other'
17
+ validations:
18
+ required: true
19
+
20
+ - type: dropdown
21
+ attributes:
22
+ label: '💻 Operating System'
23
+ multiple: true
24
+ options:
25
+ - 'Windows'
26
+ - 'macOS'
27
+ - 'Ubuntu'
28
+ - 'Other Linux'
29
+ - 'iOS'
30
+ - 'Android'
31
+ - 'Other'
32
+ validations:
33
+ required: true
34
+
35
+ - type: dropdown
36
+ attributes:
37
+ label: '📦 Deployment Platform'
9
38
  multiple: true
10
39
  options:
11
- - 'Official Preview'
12
40
  - 'Official Cloud'
13
41
  - 'Vercel'
14
42
  - 'Zeabur'
@@ -17,37 +45,25 @@ body:
17
45
  - 'Self hosting Docker'
18
46
  - 'Other'
19
47
  validations:
20
- required: true
48
+ required: false
49
+
21
50
  - type: dropdown
22
51
  attributes:
23
- label: '📦 Deploymenet mode'
52
+ label: '🔧 Deployment Mode'
24
53
  multiple: true
25
54
  options:
26
55
  - 'client db (lobe-chat image)'
27
56
  - 'client pgelite db (lobe-chat-pglite image)'
28
- - 'server db(lobe-chat-database image)'
57
+ - 'server db (lobe-chat-database image)'
29
58
  validations:
30
59
  required: true
60
+
31
61
  - type: input
32
62
  attributes:
33
63
  label: '📌 Version'
34
64
  validations:
35
65
  required: true
36
66
 
37
- - type: dropdown
38
- attributes:
39
- label: '💻 Operating System'
40
- multiple: true
41
- options:
42
- - 'Windows'
43
- - 'macOS'
44
- - 'Ubuntu'
45
- - 'Other Linux'
46
- - 'iOS'
47
- - 'Android'
48
- - 'Other'
49
- validations:
50
- required: true
51
67
  - type: dropdown
52
68
  attributes:
53
69
  label: '🌐 Browser'
@@ -60,21 +76,49 @@ body:
60
76
  - 'Other'
61
77
  validations:
62
78
  required: true
79
+
63
80
  - type: textarea
64
81
  attributes:
65
82
  label: '🐛 Bug Description'
66
83
  description: A clear and concise description of the bug, if the above option is `Other`, please also explain in detail.
67
84
  validations:
68
85
  required: true
86
+
69
87
  - type: textarea
70
88
  attributes:
71
89
  label: '📷 Recurrence Steps'
72
90
  description: A clear and concise description of how to recurrence.
91
+
73
92
  - type: textarea
74
93
  attributes:
75
94
  label: '🚦 Expected Behavior'
76
95
  description: A clear and concise description of what you expected to happen.
96
+
77
97
  - type: textarea
78
98
  attributes:
79
99
  label: '📝 Additional Information'
80
100
  description: If your problem needs further explanation, or if the issue you're seeing cannot be reproduced in a gist, please add more information here.
101
+
102
+ - type: dropdown
103
+ attributes:
104
+ label: '🛠️ Willing to Submit a PR?'
105
+ description: Would you be willing to submit a pull request to fix this bug?
106
+ options:
107
+ - 'Yes, I am willing to submit a PR'
108
+ - 'No, but I am happy to help test the fix'
109
+ validations:
110
+ required: false
111
+
112
+ - type: checkboxes
113
+ attributes:
114
+ label: '✅ Validations'
115
+ description: Before submitting the issue, please make sure you do the following
116
+ options:
117
+ - label: Read the [docs](https://lobehub.com/zh/docs).
118
+ required: true
119
+ - label: Check that there isn't [already an issue](https://github.com/lobehub/lobe-chat/issues) that reports the same bug to avoid creating a duplicate.
120
+ required: true
121
+ - label: Make sure this is a LobeChat issue and not a third-party library or provider issue.
122
+ required: true
123
+ - label: Check that this is a concrete bug. For Q&A, please use [GitHub Discussions](https://github.com/lobehub/lobe-chat/discussions) or join our [Discord Server](https://discord.gg/rGHwKq4R).
124
+ required: true
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.139.3](https://github.com/lobehub/lobe-chat/compare/v1.139.2...v1.139.3)
6
+
7
+ <sup>Released on **2025-10-21**</sup>
8
+
9
+ #### 💄 Styles
10
+
11
+ - **misc**: Show message author in minimap.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### Styles
19
+
20
+ - **misc**: Show message author in minimap, closes [#9797](https://github.com/lobehub/lobe-chat/issues/9797) ([f6daefb](https://github.com/lobehub/lobe-chat/commit/f6daefb))
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 1.139.2](https://github.com/lobehub/lobe-chat/compare/v1.139.1...v1.139.2)
31
+
32
+ <sup>Released on **2025-10-20**</sup>
33
+
34
+ #### 💄 Styles
35
+
36
+ - **misc**: Solve when desktop the sider agent list too long.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### Styles
44
+
45
+ - **misc**: Solve when desktop the sider agent list too long, closes [#9792](https://github.com/lobehub/lobe-chat/issues/9792) ([778dea3](https://github.com/lobehub/lobe-chat/commit/778dea3))
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 1.139.1](https://github.com/lobehub/lobe-chat/compare/v1.139.0...v1.139.1)
6
56
 
7
57
  <sup>Released on **2025-10-20**</sup>
@@ -39,7 +39,7 @@
39
39
  "@electron-toolkit/eslint-config-prettier": "^3.0.0",
40
40
  "@electron-toolkit/eslint-config-ts": "^3.0.0",
41
41
  "@electron-toolkit/preload": "^3.0.1",
42
- "@electron-toolkit/tsconfig": "^1.0.1",
42
+ "@electron-toolkit/tsconfig": "^2.0.0",
43
43
  "@electron-toolkit/utils": "^4.0.0",
44
44
  "@lobechat/electron-client-ipc": "workspace:*",
45
45
  "@lobechat/electron-server-ipc": "workspace:*",
package/changelog/v1.json CHANGED
@@ -1,4 +1,22 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "improvements": [
5
+ "Show message author in minimap."
6
+ ]
7
+ },
8
+ "date": "2025-10-21",
9
+ "version": "1.139.3"
10
+ },
11
+ {
12
+ "children": {
13
+ "improvements": [
14
+ "Solve when desktop the sider agent list too long."
15
+ ]
16
+ },
17
+ "date": "2025-10-20",
18
+ "version": "1.139.2"
19
+ },
2
20
  {
3
21
  "children": {
4
22
  "improvements": [
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "الانتقال إلى الرسالة رقم {{index}}",
230
230
  "nextMessage": "الرسالة التالية",
231
- "previousMessage": "الرسالة السابقة"
231
+ "previousMessage": "الرسالة السابقة",
232
+ "senderAssistant": "المساعد",
233
+ "senderUser": "أنت"
232
234
  },
233
235
  "newAgent": "مساعد جديد",
234
236
  "newGroupChat": "إنشاء دردشة جماعية جديدة",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "Отиди до съобщение № {{index}}",
230
230
  "nextMessage": "Следващо съобщение",
231
- "previousMessage": "Предишно съобщение"
231
+ "previousMessage": "Предишно съобщение",
232
+ "senderAssistant": "Асистент",
233
+ "senderUser": "Ти"
232
234
  },
233
235
  "newAgent": "Нов агент",
234
236
  "newGroupChat": "Създаване на нов групов чат",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "Zur Nachricht Nr. {{index}} springen",
230
230
  "nextMessage": "Nächste Nachricht",
231
- "previousMessage": "Vorherige Nachricht"
231
+ "previousMessage": "Vorherige Nachricht",
232
+ "senderAssistant": "Assistent",
233
+ "senderUser": "Du"
232
234
  },
233
235
  "newAgent": "Neuer Assistent",
234
236
  "newGroupChat": "Neue Gruppe erstellen",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "Jump to message {{index}}",
230
230
  "nextMessage": "Next message",
231
- "previousMessage": "Previous message"
231
+ "previousMessage": "Previous message",
232
+ "senderAssistant": "Assistant",
233
+ "senderUser": "You"
232
234
  },
233
235
  "newAgent": "New Assistant",
234
236
  "newGroupChat": "New Group Chat",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "Ir al mensaje número {{index}}",
230
230
  "nextMessage": "Mensaje siguiente",
231
- "previousMessage": "Mensaje anterior"
231
+ "previousMessage": "Mensaje anterior",
232
+ "senderAssistant": "Asistente",
233
+ "senderUser": "Tú"
232
234
  },
233
235
  "newAgent": "Nuevo asistente",
234
236
  "newGroupChat": "Crear nuevo chat de grupo",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "رفتن به پیام شماره {{index}}",
230
230
  "nextMessage": "پیام بعدی",
231
- "previousMessage": "پیام قبلی"
231
+ "previousMessage": "پیام قبلی",
232
+ "senderAssistant": "دستیار",
233
+ "senderUser": "شما"
232
234
  },
233
235
  "newAgent": "دستیار جدید",
234
236
  "newGroupChat": "ایجاد چت گروهی جدید",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "Aller au message n° {{index}}",
230
230
  "nextMessage": "Message suivant",
231
- "previousMessage": "Message précédent"
231
+ "previousMessage": "Message précédent",
232
+ "senderAssistant": "Assistant",
233
+ "senderUser": "Vous"
232
234
  },
233
235
  "newAgent": "Nouvel agent",
234
236
  "newGroupChat": "Nouveau groupe de discussion",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "Vai al messaggio n. {{index}}",
230
230
  "nextMessage": "Messaggio successivo",
231
- "previousMessage": "Messaggio precedente"
231
+ "previousMessage": "Messaggio precedente",
232
+ "senderAssistant": "Assistente",
233
+ "senderUser": "Tu"
232
234
  },
233
235
  "newAgent": "Nuovo assistente",
234
236
  "newGroupChat": "Nuova chat di gruppo",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "メッセージ {{index}} へジャンプ",
230
230
  "nextMessage": "次のメッセージ",
231
- "previousMessage": "前のメッセージ"
231
+ "previousMessage": "前のメッセージ",
232
+ "senderAssistant": "アシスタント",
233
+ "senderUser": "あなた"
232
234
  },
233
235
  "newAgent": "新しいエージェント",
234
236
  "newGroupChat": "新しいグループチャットを作成",
@@ -4,7 +4,7 @@
4
4
  },
5
5
  "active": "활성",
6
6
  "agentDefaultMessage": "안녕하세요, 저는 **{{name}}**입니다. 지금 바로 저와 대화를 시작하시거나 [도우미 설정]({{url}})으로 가셔서 제 정보를 완성하실 수 있습니다.",
7
- "agentDefaultMessageWithSystemRole": "안녕하세요, 저는 **{{name}}**입니다. {{systemRole}}입니다. 대화를 시작해 봅시다!",
7
+ "agentDefaultMessageWithSystemRole": "안녕하세요, 저는 **{{name}}**입니다. 대화를 시작해 봅시다!",
8
8
  "agentDefaultMessageWithoutEdit": "안녕하세요, 저는 **{{name}}**입니다. 대화를 시작해보세요!",
9
9
  "agents": "도우미",
10
10
  "artifact": {
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "{{index}}번째 메시지로 이동",
230
230
  "nextMessage": "다음 메시지",
231
- "previousMessage": "이전 메시지"
231
+ "previousMessage": "이전 메시지",
232
+ "senderAssistant": "도우미",
233
+ "senderUser": "당신"
232
234
  },
233
235
  "newAgent": "새 도우미",
234
236
  "newGroupChat": "새 그룹 채팅 만들기",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "Ga naar bericht {{index}}",
230
230
  "nextMessage": "Volgend bericht",
231
- "previousMessage": "Vorig bericht"
231
+ "previousMessage": "Vorig bericht",
232
+ "senderAssistant": "Assistent",
233
+ "senderUser": "Jij"
232
234
  },
233
235
  "newAgent": "Nieuwe assistent",
234
236
  "newGroupChat": "Nieuwe groepschat",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "Przejdź do wiadomości nr {{index}}",
230
230
  "nextMessage": "Następna wiadomość",
231
- "previousMessage": "Poprzednia wiadomość"
231
+ "previousMessage": "Poprzednia wiadomość",
232
+ "senderAssistant": "Asystent",
233
+ "senderUser": "Ty"
232
234
  },
233
235
  "newAgent": "Nowy asystent",
234
236
  "newGroupChat": "Utwórz nowy czat grupowy",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "Ir para a mensagem nº {{index}}",
230
230
  "nextMessage": "Próxima mensagem",
231
- "previousMessage": "Mensagem anterior"
231
+ "previousMessage": "Mensagem anterior",
232
+ "senderAssistant": "Assistente",
233
+ "senderUser": "Você"
232
234
  },
233
235
  "newAgent": "Novo Assistente",
234
236
  "newGroupChat": "Criar novo grupo",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "Перейти к сообщению № {{index}}",
230
230
  "nextMessage": "Следующее сообщение",
231
- "previousMessage": "Предыдущее сообщение"
231
+ "previousMessage": "Предыдущее сообщение",
232
+ "senderAssistant": "Ассистент",
233
+ "senderUser": "Вы"
232
234
  },
233
235
  "newAgent": "Создать помощника",
234
236
  "newGroupChat": "Создать групповой чат",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "{{index}} numaralı mesaja atla",
230
230
  "nextMessage": "Sonraki mesaj",
231
- "previousMessage": "Önceki mesaj"
231
+ "previousMessage": "Önceki mesaj",
232
+ "senderAssistant": "Asistan",
233
+ "senderUser": "Sen"
232
234
  },
233
235
  "newAgent": "Yeni Asistan",
234
236
  "newGroupChat": "Yeni grup sohbeti oluştur",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "Chuyển đến tin nhắn thứ {{index}}",
230
230
  "nextMessage": "Tin nhắn tiếp theo",
231
- "previousMessage": "Tin nhắn trước"
231
+ "previousMessage": "Tin nhắn trước",
232
+ "senderAssistant": "Trợ lý",
233
+ "senderUser": "Bạn"
232
234
  },
233
235
  "newAgent": "Tạo trợ lý mới",
234
236
  "newGroupChat": "Tạo nhóm mới",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "跳转至第 {{index}} 条消息",
230
230
  "nextMessage": "下一条消息",
231
- "previousMessage": "上一条消息"
231
+ "previousMessage": "上一条消息",
232
+ "senderAssistant": "助手",
233
+ "senderUser": "你"
232
234
  },
233
235
  "newAgent": "新建助手",
234
236
  "newGroupChat": "新建群聊",
@@ -228,7 +228,9 @@
228
228
  "minimap": {
229
229
  "jumpToMessage": "跳轉至第 {{index}} 條訊息",
230
230
  "nextMessage": "下一條訊息",
231
- "previousMessage": "上一條訊息"
231
+ "previousMessage": "上一條訊息",
232
+ "senderAssistant": "助理",
233
+ "senderUser": "您"
232
234
  },
233
235
  "newAgent": "新建助手",
234
236
  "newGroupChat": "建立群組",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.139.1",
3
+ "version": "1.139.3",
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",
@@ -126,7 +126,7 @@
126
126
  "dependencies": {
127
127
  "@ant-design/icons": "^5.6.1",
128
128
  "@ant-design/pro-components": "^2.8.10",
129
- "@anthropic-ai/sdk": "^0.65.0",
129
+ "@anthropic-ai/sdk": "^0.67.0",
130
130
  "@auth/core": "^0.40.0",
131
131
  "@aws-sdk/client-s3": "~3.893.0",
132
132
  "@aws-sdk/s3-request-presigner": "~3.893.0",
@@ -238,7 +238,7 @@
238
238
  "oidc-provider": "^9.5.1",
239
239
  "ollama": "^0.6.0",
240
240
  "openai": "^4.104.0",
241
- "openapi-fetch": "^0.9.8",
241
+ "openapi-fetch": "^0.14.0",
242
242
  "partial-json": "^0.1.7",
243
243
  "path-browserify-esm": "^1.0.6",
244
244
  "pdf-parse": "^1.1.1",
@@ -13,6 +13,7 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "@aws-sdk/client-bedrock-runtime": "^3.862.0",
16
+ "@huggingface/inference": "^4.11.3",
16
17
  "@lobechat/const": "workspace:*",
17
18
  "@lobechat/types": "workspace:*",
18
19
  "@lobechat/utils": "workspace:*",
@@ -10,12 +10,12 @@
10
10
  "@opentelemetry/auto-instrumentations-node": "^0.65.0",
11
11
  "@opentelemetry/exporter-metrics-otlp-http": "^0.206.0",
12
12
  "@opentelemetry/exporter-trace-otlp-http": "^0.206.0",
13
- "@opentelemetry/instrumentation": "^0.205.0",
13
+ "@opentelemetry/instrumentation": "^0.206.0",
14
14
  "@opentelemetry/instrumentation-http": "^0.205.0",
15
15
  "@opentelemetry/instrumentation-pg": "^0.59.0",
16
16
  "@opentelemetry/resources": "^2.0.1",
17
17
  "@opentelemetry/sdk-metrics": "^2.0.1",
18
- "@opentelemetry/sdk-node": "^0.205.0",
18
+ "@opentelemetry/sdk-node": "^0.206.0",
19
19
  "@opentelemetry/sdk-trace-node": "^2.0.1",
20
20
  "@opentelemetry/semantic-conventions": "^1.36.0",
21
21
  "@vercel/otel": "^1.13.0",
@@ -27,12 +27,13 @@ const Top = () => {
27
27
 
28
28
  const Nav = memo(() => {
29
29
  const theme = useTheme();
30
- const isSingleMode = useIsSingleMode()
30
+ const isSingleMode = useIsSingleMode();
31
31
  const inZenMode = useGlobalStore(systemStatusSelectors.inZenMode);
32
32
  const { showPinList } = useServerConfigStore(featureFlagsSelectors);
33
33
 
34
34
  return (
35
- !inZenMode && !isSingleMode && (
35
+ !inZenMode &&
36
+ !isSingleMode && (
36
37
  <SideNav
37
38
  avatar={
38
39
  <div className={electronStylish.nodrag}>
@@ -54,11 +55,14 @@ const Nav = memo(() => {
54
55
  }}
55
56
  topActions={
56
57
  <Suspense>
57
- <div className={electronStylish.nodrag} style={{
58
- display: 'flex',
59
- flexDirection: 'column',
60
- maxHeight: "calc(100vh - 150px)"
61
- }}>
58
+ <div
59
+ className={electronStylish.nodrag}
60
+ style={{
61
+ display: 'flex',
62
+ flexDirection: 'column',
63
+ maxHeight: isDesktop ? 'calc(100vh - 180px)' : 'calc(100vh - 150px)',
64
+ }}
65
+ >
62
66
  <Top />
63
67
  {showPinList && <PinList />}
64
68
  </div>
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { Icon } from '@lobehub/ui';
4
- import { Tooltip } from 'antd';
4
+ import { Popover, Tooltip } from 'antd';
5
5
  import { createStyles, useTheme } from 'antd-style';
6
6
  import debug from 'debug';
7
7
  import { ChevronDown, ChevronUp } from 'lucide-react';
@@ -114,6 +114,19 @@ const useStyles = createStyles(({ css, token }) => ({
114
114
  indicatorContentActive: css`
115
115
  background: ${token.colorPrimary};
116
116
  `,
117
+ popoverContent: css`
118
+ max-width: 300px;
119
+ `,
120
+ popoverLabel: css`
121
+ margin-block-end: 4px;
122
+ font-size: 12px;
123
+ font-weight: 600;
124
+ color: ${token.colorTextSecondary};
125
+ `,
126
+ popoverText: css`
127
+ color: ${token.colorText};
128
+ word-break: break-word;
129
+ `,
117
130
  rail: css`
118
131
  pointer-events: auto;
119
132
 
@@ -174,6 +187,7 @@ const getPreviewText = (content: string | undefined) => {
174
187
  interface MinimapIndicator {
175
188
  id: string;
176
189
  preview: string;
190
+ role: 'user' | 'assistant';
177
191
  virtuosoIndex: number;
178
192
  width: number;
179
193
  }
@@ -203,6 +217,7 @@ const ChatMinimap = () => {
203
217
  acc.push({
204
218
  id: message.id,
205
219
  preview: getPreviewText(message.content),
220
+ role: message.role,
206
221
  virtuosoIndex,
207
222
  width: getIndicatorWidth(message.content),
208
223
  });
@@ -317,16 +332,20 @@ const ChatMinimap = () => {
317
332
  </button>
318
333
  </Tooltip>
319
334
  <Flexbox className={styles.railContent}>
320
- {indicators.map(({ id, width, preview, virtuosoIndex }, position) => {
335
+ {indicators.map(({ id, width, preview, role, virtuosoIndex }, position) => {
321
336
  const isActive = activeIndicatorPosition === position;
337
+ const senderLabel =
338
+ role === 'user' ? t('minimap.senderUser') : t('minimap.senderAssistant');
339
+
340
+ const popoverContent = preview ? (
341
+ <div className={styles.popoverContent}>
342
+ <div className={styles.popoverLabel}>{senderLabel}</div>
343
+ <div className={styles.popoverText}>{preview}</div>
344
+ </div>
345
+ ) : undefined;
322
346
 
323
347
  return (
324
- <Tooltip
325
- key={id}
326
- mouseEnterDelay={0.1}
327
- placement={'left'}
328
- title={preview || undefined}
329
- >
348
+ <Popover content={popoverContent} key={id} mouseEnterDelay={0.1} placement={'left'}>
330
349
  <button
331
350
  aria-current={isActive ? 'true' : undefined}
332
351
  aria-label={t('minimap.jumpToMessage', { index: position + 1 })}
@@ -344,7 +363,7 @@ const ChatMinimap = () => {
344
363
  )}
345
364
  />
346
365
  </button>
347
- </Tooltip>
366
+ </Popover>
348
367
  );
349
368
  })}
350
369
  </Flexbox>
@@ -50,9 +50,12 @@ const StoreInitialization = memo(() => {
50
50
  * The store function of `isLogin` will both consider the values of `enableAuth` and `isSignedIn`.
51
51
  * But during initialization, the value of `enableAuth` might be incorrect cause of the async fetch.
52
52
  * So we need to use `isSignedIn` only to determine whether request for the default agent config and user state.
53
+ *
54
+ * IMPORTANT: Explicitly convert to boolean to avoid passing null/undefined downstream,
55
+ * which would cause unnecessary API requests with invalid login state.
53
56
  */
54
57
  const isDBInited = useGlobalStore(systemStatusSelectors.isDBInited);
55
- const isLoginOnInit = isDBInited && (enableNextAuth ? isSignedIn : isLogin);
58
+ const isLoginOnInit = isDBInited ? Boolean(enableNextAuth ? isSignedIn : isLogin) : false;
56
59
 
57
60
  // init inbox agent and default agent config
58
61
  useInitAgentStore(isLoginOnInit, serverConfig.defaultAgent?.config);
@@ -34,6 +34,19 @@ export const useClientDataSWR: SWRHook = (key, fetch, config) =>
34
34
  ? 1500
35
35
  : // web 300s
36
36
  5 * 60 * 1000,
37
+ // Custom error retry logic: don't retry on 401 errors
38
+ onErrorRetry: (error: any, key: any, config: any, revalidate: any, { retryCount }: any) => {
39
+ // Check if error is marked as non-retryable (e.g., 401 authentication errors)
40
+ if (error?.meta?.shouldRetry === false) {
41
+ return;
42
+ }
43
+ // For other errors, use default SWR retry behavior
44
+ // Default: exponential backoff, max 5 retries
45
+ if (retryCount >= 5) return;
46
+ const exponentialDelay = 1000 * Math.pow(2, Math.min(retryCount, 10));
47
+ const timeout = Math.min(exponentialDelay, 30_000);
48
+ setTimeout(() => revalidate({ retryCount }), timeout);
49
+ },
37
50
  refreshWhenOffline: false,
38
51
  revalidateOnFocus: true,
39
52
  revalidateOnReconnect: true,
@@ -10,6 +10,10 @@ import type { LambdaRouter } from '@/server/routers/lambda';
10
10
 
11
11
  const log = debug('lobe-image:lambda-client');
12
12
 
13
+ // 401 error debouncing: prevent showing multiple login notifications in short time
14
+ let last401Time = 0;
15
+ const MIN_401_INTERVAL = 5000; // 5 seconds
16
+
13
17
  // handle error
14
18
  const errorHandlingLink: TRPCLink<LambdaRouter> = () => {
15
19
  return ({ op, next }) =>
@@ -18,10 +22,9 @@ const errorHandlingLink: TRPCLink<LambdaRouter> = () => {
18
22
  complete: () => observer.complete(),
19
23
  error: async (err) => {
20
24
  const showError = (op.context?.showNotification as boolean) ?? true;
25
+ const status = err.data?.httpStatus as number;
21
26
 
22
27
  if (showError) {
23
- const status = err.data?.httpStatus as number;
24
-
25
28
  const { loginRequired } = await import('@/components/Error/loginRequiredNotification');
26
29
  const { fetchErrorNotification } = await import(
27
30
  '@/components/Error/fetchErrorNotification'
@@ -29,7 +32,14 @@ const errorHandlingLink: TRPCLink<LambdaRouter> = () => {
29
32
 
30
33
  switch (status) {
31
34
  case 401: {
32
- loginRequired.redirect();
35
+ // Debounce: only show login notification once every 5 seconds
36
+ const now = Date.now();
37
+ if (now - last401Time > MIN_401_INTERVAL) {
38
+ last401Time = now;
39
+ loginRequired.redirect();
40
+ }
41
+ // Mark error as non-retryable to prevent SWR infinite retry loop
42
+ err.meta = { ...err.meta, shouldRetry: false };
33
43
  break;
34
44
  }
35
45
 
@@ -247,6 +247,8 @@ export default {
247
247
  jumpToMessage: '跳转至第 {{index}} 条消息',
248
248
  nextMessage: '下一条消息',
249
249
  previousMessage: '上一条消息',
250
+ senderAssistant: '助手',
251
+ senderUser: '你',
250
252
  },
251
253
 
252
254
  newAgent: '新建助手',
@@ -160,7 +160,8 @@ export const createChatSlice: StateCreator<
160
160
  },
161
161
  useFetchAgentConfig: (isLogin, sessionId) =>
162
162
  useClientDataSWR<LobeAgentConfig>(
163
- isLogin && !sessionId.startsWith('cg_')
163
+ // Only fetch when login status is explicitly true (not null/undefined)
164
+ isLogin === true && !sessionId.startsWith('cg_')
164
165
  ? ([FETCH_AGENT_CONFIG_KEY, sessionId] as const)
165
166
  : null,
166
167
  ([, id]: readonly [string, string]) => sessionService.getSessionConfig(id),
@@ -192,7 +193,8 @@ export const createChatSlice: StateCreator<
192
193
 
193
194
  useInitInboxAgentStore: (isLogin, defaultAgentConfig) =>
194
195
  useOnlyFetchOnceSWR<PartialDeep<LobeAgentConfig>>(
195
- !!isLogin ? 'fetchInboxAgentConfig' : null,
196
+ // Only fetch when login status is explicitly true (not null/undefined/false)
197
+ isLogin === true ? 'fetchInboxAgentConfig' : null,
196
198
  () => sessionService.getSessionConfig(INBOX_SESSION_ID),
197
199
  {
198
200
  onSuccess: (data) => {
@@ -237,10 +237,12 @@ export const createAiProviderSlice: StateCreator<
237
237
 
238
238
  useFetchAiProviderRuntimeState: (isLogin) => {
239
239
  const isAuthLoaded = authSelectors.isLoaded(useUserStore.getState());
240
+ // Only fetch when auth is loaded and login status is explicitly defined (true or false)
241
+ // Prevents unnecessary requests when login state is null/undefined
242
+ const shouldFetch =
243
+ isAuthLoaded && !isDeprecatedEdition && isLogin !== null && isLogin !== undefined;
240
244
  return useClientDataSWR<AiProviderRuntimeStateWithBuiltinModels | undefined>(
241
- isAuthLoaded && !isDeprecatedEdition
242
- ? [AiProviderSwrKey.fetchAiProviderRuntimeState, isLogin]
243
- : null,
245
+ shouldFetch ? [AiProviderSwrKey.fetchAiProviderRuntimeState, isLogin] : null,
244
246
  async ([, isLogin]) => {
245
247
  const [{ LOBE_DEFAULT_MODEL_LIST: builtinAiModelList }, { DEFAULT_MODEL_PROVIDER_LIST }] =
246
248
  await Promise.all([import('model-bank'), import('@/config/modelProviders')]);
@@ -428,11 +428,7 @@ export const chatMessage: StateCreator<
428
428
  internal_toggleMessageLoading(true, tempId);
429
429
  }
430
430
 
431
- console.log('internal_createMessafe', message);
432
-
433
431
  try {
434
- console.log('internal_createMessage: Trying to call messageService.createMessage', message);
435
-
436
432
  const id = await messageService.createMessage(message);
437
433
  if (!context?.skipRefresh) {
438
434
  internal_toggleMessageLoading(true, tempId);