@lobehub/chat 1.94.2 → 1.94.4

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 (55) hide show
  1. package/.github/scripts/create-failure-issue.js +256 -0
  2. package/.github/workflows/auto-i18n.yml +359 -0
  3. package/CHANGELOG.md +42 -0
  4. package/changelog/v1.json +14 -0
  5. package/locales/ar/setting.json +13 -1
  6. package/locales/bg-BG/setting.json +13 -1
  7. package/locales/de-DE/setting.json +13 -1
  8. package/locales/en-US/setting.json +13 -1
  9. package/locales/es-ES/setting.json +13 -1
  10. package/locales/fa-IR/setting.json +13 -1
  11. package/locales/fr-FR/setting.json +13 -1
  12. package/locales/it-IT/setting.json +13 -1
  13. package/locales/ja-JP/setting.json +13 -1
  14. package/locales/ko-KR/setting.json +13 -1
  15. package/locales/nl-NL/setting.json +13 -1
  16. package/locales/pl-PL/setting.json +13 -1
  17. package/locales/pt-BR/setting.json +13 -1
  18. package/locales/ru-RU/setting.json +13 -1
  19. package/locales/tr-TR/setting.json +13 -1
  20. package/locales/vi-VN/setting.json +13 -1
  21. package/locales/zh-CN/setting.json +13 -1
  22. package/locales/zh-TW/setting.json +13 -1
  23. package/package.json +2 -2
  24. package/src/app/[variants]/(main)/settings/common/features/ChatAppearance/ChatTransitionPreview.tsx +111 -0
  25. package/src/app/[variants]/(main)/settings/common/features/ChatAppearance/index.tsx +50 -3
  26. package/src/components/Thinking/index.tsx +4 -2
  27. package/src/config/modelProviders/anthropic.ts +1 -6
  28. package/src/config/modelProviders/baichuan.ts +4 -8
  29. package/src/config/modelProviders/google.ts +4 -4
  30. package/src/config/modelProviders/lmstudio.ts +4 -4
  31. package/src/config/modelProviders/minimax.ts +3 -3
  32. package/src/config/modelProviders/moonshot.ts +4 -4
  33. package/src/config/modelProviders/openai.ts +1 -3
  34. package/src/config/modelProviders/perplexity.ts +3 -3
  35. package/src/config/modelProviders/qwen.ts +4 -4
  36. package/src/config/modelProviders/search1api.ts +4 -4
  37. package/src/config/modelProviders/spark.ts +4 -4
  38. package/src/config/modelProviders/stepfun.ts +4 -4
  39. package/src/config/modelProviders/vertexai.ts +1 -3
  40. package/src/config/modelProviders/volcengine.ts +4 -4
  41. package/src/config/modelProviders/wenxin.ts +3 -3
  42. package/src/const/settings/common.ts +1 -0
  43. package/src/features/Conversation/Messages/Assistant/Reasoning/index.tsx +11 -1
  44. package/src/features/Conversation/components/ChatItem/index.tsx +6 -2
  45. package/src/features/Conversation/components/MarkdownElements/LobeThinking/Render.tsx +4 -0
  46. package/src/features/Conversation/components/MarkdownElements/Thinking/Render.tsx +12 -1
  47. package/src/locales/default/setting.ts +12 -0
  48. package/src/services/chat.ts +15 -6
  49. package/src/store/user/slices/settings/selectors/general.test.ts +1 -0
  50. package/src/store/user/slices/settings/selectors/general.ts +2 -0
  51. package/src/types/aiProvider.ts +11 -11
  52. package/src/types/llm.ts +8 -10
  53. package/src/types/user/settings/general.ts +3 -0
  54. package/src/utils/fetch/__tests__/fetchSSE.test.ts +57 -12
  55. package/src/utils/fetch/fetchSSE.ts +22 -15
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "موضوع حورية البحر"
242
242
  },
243
- "title": "مظهر الدردشة"
243
+ "title": "مظهر الدردشة",
244
+ "transitionMode": {
245
+ "desc": "رسوم انتقال رسائل الدردشة",
246
+ "options": {
247
+ "fadeIn": "تلاشي",
248
+ "none": {
249
+ "desc": "يعتمد هذا على طريقة إخراج استجابة النموذج، يرجى الاختبار بنفسك.",
250
+ "value": "بدون"
251
+ },
252
+ "smooth": "سلس"
253
+ },
254
+ "title": "رسوم الانتقال"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "Тема русалка"
242
242
  },
243
- "title": "Външен вид на чата"
243
+ "title": "Външен вид на чата",
244
+ "transitionMode": {
245
+ "desc": "Анимация на прехода на съобщенията в чата",
246
+ "options": {
247
+ "fadeIn": "Постепенно появяване",
248
+ "none": {
249
+ "desc": "Зависи от начина на отговор на модела, моля, тествайте сами.",
250
+ "value": "Без"
251
+ },
252
+ "smooth": "Плавно"
253
+ },
254
+ "title": "Анимация на прехода"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "Mermaid-Thema"
242
242
  },
243
- "title": "Chatdesign"
243
+ "title": "Chatdesign",
244
+ "transitionMode": {
245
+ "desc": "Übergangsanimation der Chatnachrichten",
246
+ "options": {
247
+ "fadeIn": "Einblenden",
248
+ "none": {
249
+ "desc": "Dies hängt von der Art der Antwort des Modells ab, bitte testen Sie es selbst.",
250
+ "value": "Keine"
251
+ },
252
+ "smooth": "Sanft"
253
+ },
254
+ "title": "Übergangsanimation"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "Mermaid Theme"
242
242
  },
243
- "title": "Chat Appearance"
243
+ "title": "Chat Appearance",
244
+ "transitionMode": {
245
+ "desc": "Transition animation for chat messages",
246
+ "options": {
247
+ "fadeIn": "Fade In",
248
+ "none": {
249
+ "desc": "This depends on the model's response output method; please test it yourself.",
250
+ "value": "None"
251
+ },
252
+ "smooth": "Smooth"
253
+ },
254
+ "title": "Transition Animation"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "Tema Sirena"
242
242
  },
243
- "title": "Apariencia del Chat"
243
+ "title": "Apariencia del Chat",
244
+ "transitionMode": {
245
+ "desc": "Animación de transición de los mensajes de chat",
246
+ "options": {
247
+ "fadeIn": "Aparecer gradualmente",
248
+ "none": {
249
+ "desc": "Depende de la forma en que el modelo genera la respuesta, por favor pruébelo usted mismo.",
250
+ "value": "Ninguna"
251
+ },
252
+ "smooth": "Suave"
253
+ },
254
+ "title": "Animación de transición"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "تم مرمید"
242
242
  },
243
- "title": "ظاهر چت"
243
+ "title": "ظاهر چت",
244
+ "transitionMode": {
245
+ "desc": "انیمیشن انتقال پیام‌های چت",
246
+ "options": {
247
+ "fadeIn": "نمایش تدریجی",
248
+ "none": {
249
+ "desc": "این بستگی به نحوه خروجی مدل دارد، لطفاً خودتان تست کنید.",
250
+ "value": "بدون انیمیشن"
251
+ },
252
+ "smooth": "نرم"
253
+ },
254
+ "title": "انیمیشن انتقال"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "Thème Sirène"
242
242
  },
243
- "title": "Apparence du chat"
243
+ "title": "Apparence du chat",
244
+ "transitionMode": {
245
+ "desc": "Animation de transition des messages de chat",
246
+ "options": {
247
+ "fadeIn": "Fondu en entrée",
248
+ "none": {
249
+ "desc": "Cela dépend de la manière dont le modèle génère la réponse, veuillez tester par vous-même.",
250
+ "value": "Aucun"
251
+ },
252
+ "smooth": "Fluide"
253
+ },
254
+ "title": "Animation de transition"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "Tema Sirena"
242
242
  },
243
- "title": "Aspetto della Chat"
243
+ "title": "Aspetto della Chat",
244
+ "transitionMode": {
245
+ "desc": "Animazione di transizione dei messaggi di chat",
246
+ "options": {
247
+ "fadeIn": "Dissolvenza in entrata",
248
+ "none": {
249
+ "desc": "Dipende dal modo in cui il modello restituisce la risposta, si prega di testare autonomamente.",
250
+ "value": "Nessuna"
251
+ },
252
+ "smooth": "Fluido"
253
+ },
254
+ "title": "Animazione di transizione"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "マーメイドテーマ"
242
242
  },
243
- "title": "チャットの外観"
243
+ "title": "チャットの外観",
244
+ "transitionMode": {
245
+ "desc": "チャットメッセージの遷移アニメーション",
246
+ "options": {
247
+ "fadeIn": "フェードイン",
248
+ "none": {
249
+ "desc": "これはモデルの応答出力方法によりますので、ご自身でテストしてください。",
250
+ "value": "なし"
251
+ },
252
+ "smooth": "スムーズ"
253
+ },
254
+ "title": "遷移アニメーション"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "인어 테마"
242
242
  },
243
- "title": "채팅 외관"
243
+ "title": "채팅 외관",
244
+ "transitionMode": {
245
+ "desc": "채팅 메시지의 전환 애니메이션",
246
+ "options": {
247
+ "fadeIn": "서서히 나타남",
248
+ "none": {
249
+ "desc": "이는 모델의 응답 출력 방식에 따라 다르므로 직접 테스트해 보세요.",
250
+ "value": "없음"
251
+ },
252
+ "smooth": "부드럽게"
253
+ },
254
+ "title": "전환 애니메이션"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "Mermaid-thema"
242
242
  },
243
- "title": "Chat uiterlijk"
243
+ "title": "Chat uiterlijk",
244
+ "transitionMode": {
245
+ "desc": "Overgangsanimatie van chatberichten",
246
+ "options": {
247
+ "fadeIn": "Vervagen",
248
+ "none": {
249
+ "desc": "Dit hangt af van de manier waarop het model reageert; test dit zelf.",
250
+ "value": "Geen"
251
+ },
252
+ "smooth": "Vloeiend"
253
+ },
254
+ "title": "Overgangsanimatie"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "Motyw Syreny"
242
242
  },
243
- "title": "Wygląd czatu"
243
+ "title": "Wygląd czatu",
244
+ "transitionMode": {
245
+ "desc": "Animacja przejścia wiadomości czatu",
246
+ "options": {
247
+ "fadeIn": "Pojawianie się",
248
+ "none": {
249
+ "desc": "To zależy od sposobu generowania odpowiedzi przez model, proszę przetestować samodzielnie.",
250
+ "value": "Brak"
251
+ },
252
+ "smooth": "Płynne"
253
+ },
254
+ "title": "Animacja przejścia"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "Tema Sereia"
242
242
  },
243
- "title": "Aparência do Chat"
243
+ "title": "Aparência do Chat",
244
+ "transitionMode": {
245
+ "desc": "Animação de transição das mensagens do chat",
246
+ "options": {
247
+ "fadeIn": "Desvanecer",
248
+ "none": {
249
+ "desc": "Depende da forma como o modelo responde, por favor teste por conta própria.",
250
+ "value": "Nenhuma"
251
+ },
252
+ "smooth": "Suave"
253
+ },
254
+ "title": "Animação de transição"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "Тема Русалки"
242
242
  },
243
- "title": "Внешний вид чата"
243
+ "title": "Внешний вид чата",
244
+ "transitionMode": {
245
+ "desc": "Анимация перехода сообщений чата",
246
+ "options": {
247
+ "fadeIn": "Появление",
248
+ "none": {
249
+ "desc": "Зависит от способа вывода ответа модели, рекомендуется протестировать самостоятельно.",
250
+ "value": "Нет"
251
+ },
252
+ "smooth": "Плавно"
253
+ },
254
+ "title": "Анимация перехода"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "Deniz Kızı Teması"
242
242
  },
243
- "title": "Sohbet Görünümü"
243
+ "title": "Sohbet Görünümü",
244
+ "transitionMode": {
245
+ "desc": "Sohbet mesajlarının geçiş animasyonu",
246
+ "options": {
247
+ "fadeIn": "Solma",
248
+ "none": {
249
+ "desc": "Bu, modelin yanıt çıktısına bağlıdır, lütfen kendiniz test edin.",
250
+ "value": "Yok"
251
+ },
252
+ "smooth": "Yumuşak"
253
+ },
254
+ "title": "Geçiş Animasyonu"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "Chủ đề Nàng Tiên Cá"
242
242
  },
243
- "title": "Giao diện trò chuyện"
243
+ "title": "Giao diện trò chuyện",
244
+ "transitionMode": {
245
+ "desc": "Hiệu ứng chuyển tiếp của tin nhắn trò chuyện",
246
+ "options": {
247
+ "fadeIn": "Mờ dần",
248
+ "none": {
249
+ "desc": "Điều này phụ thuộc vào cách mô hình phản hồi, vui lòng tự kiểm tra.",
250
+ "value": "Không"
251
+ },
252
+ "smooth": "Mượt mà"
253
+ },
254
+ "title": "Hiệu ứng chuyển tiếp"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "Mermaid 主题"
242
242
  },
243
- "title": "聊天外观"
243
+ "title": "聊天外观",
244
+ "transitionMode": {
245
+ "desc": "聊天消息的过渡动画",
246
+ "options": {
247
+ "fadeIn": "淡入",
248
+ "none": {
249
+ "desc": "这取决于模型的响应输出方式,请自行测试。",
250
+ "value": "无"
251
+ },
252
+ "smooth": "平滑"
253
+ },
254
+ "title": "过渡动画"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
@@ -240,7 +240,19 @@
240
240
  "mermaidTheme": {
241
241
  "title": "美人魚主題"
242
242
  },
243
- "title": "聊天外觀"
243
+ "title": "聊天外觀",
244
+ "transitionMode": {
245
+ "desc": "聊天訊息的過渡動畫",
246
+ "options": {
247
+ "fadeIn": "淡入",
248
+ "none": {
249
+ "desc": "這取決於模型的回應輸出方式,請自行測試。",
250
+ "value": "無"
251
+ },
252
+ "smooth": "平滑"
253
+ },
254
+ "title": "過渡動畫"
255
+ }
244
256
  },
245
257
  "settingCommon": {
246
258
  "lang": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.94.2",
3
+ "version": "1.94.4",
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",
@@ -346,7 +346,7 @@
346
346
  "semantic-release": "^21.1.2",
347
347
  "serwist": "^9.0.14",
348
348
  "stylelint": "^15.11.0",
349
- "tsx": "^4.19.4",
349
+ "tsx": "~4.19.4",
350
350
  "typescript": "^5.8.3",
351
351
  "unified": "^11.0.5",
352
352
  "unist-util-visit": "^5.0.0",
@@ -0,0 +1,111 @@
1
+ import { ActionIconGroup, Block } from '@lobehub/ui';
2
+ import { ChatItem } from '@lobehub/ui/chat';
3
+ import { useTheme } from 'antd-style';
4
+ import { RotateCwIcon } from 'lucide-react';
5
+ import { memo, useEffect, useMemo, useState } from 'react';
6
+ import { useTranslation } from 'react-i18next';
7
+
8
+ import { DEFAULT_INBOX_AVATAR } from '@/const/meta';
9
+ import { UserGeneralConfig } from '@/types/user/settings';
10
+
11
+ const data = `
12
+ ### Features
13
+
14
+ **Key Highlights**
15
+ - 🌐 Multi-model: GPT-4/Gemini/Ollama
16
+ - 🖼️ Vision: \`gpt-4-vision\` integration
17
+ - 🛠️ Plugins: Function Calling & real-time data
18
+ `;
19
+
20
+ const streamingSpeed = 25; // ms per character
21
+
22
+ interface ChatTransitionPreviewProps {
23
+ mode: UserGeneralConfig['transitionMode'];
24
+ }
25
+
26
+ const randomInlRange = (min = 0, max = min + 10) => {
27
+ return Math.floor(Math.random() * (max - min + 1)) + min;
28
+ };
29
+
30
+ const ChatTransitionPreview = memo<ChatTransitionPreviewProps>(({ mode }) => {
31
+ const [streamedContent, setStreamedContent] = useState(() => {
32
+ if (mode === 'none') {
33
+ return data.slice(0, Math.max(0, randomInlRange(10, 100)));
34
+ }
35
+ return '';
36
+ });
37
+
38
+ const chunkStep = useMemo(() => {
39
+ if (mode === 'none') {
40
+ return Math.ceil(data.length / randomInlRange(3, 5));
41
+ }
42
+ return 3;
43
+ }, [mode]);
44
+
45
+ const [isStreaming, setIsStreaming] = useState(true);
46
+ const { t } = useTranslation('common');
47
+ const token = useTheme();
48
+
49
+ useEffect(() => {
50
+ if (!isStreaming) return;
51
+
52
+ let currentPosition = 0;
53
+ if (streamedContent.length > 0) {
54
+ currentPosition = streamedContent.length;
55
+ }
56
+
57
+ const intervalId = setInterval(() => {
58
+ if (currentPosition < data.length) {
59
+ // Stream character by character
60
+ const nextChunkSize = Math.min(chunkStep, data.length - currentPosition);
61
+ const nextContent = data.slice(0, Math.max(0, currentPosition + nextChunkSize));
62
+ setStreamedContent(nextContent);
63
+ currentPosition += nextChunkSize;
64
+ } else {
65
+ clearInterval(intervalId);
66
+ setIsStreaming(false);
67
+ }
68
+ }, streamingSpeed);
69
+
70
+ return () => clearInterval(intervalId);
71
+ }, [isStreaming, streamedContent.length, chunkStep]);
72
+
73
+ const handleReset = () => {
74
+ setStreamedContent('');
75
+ setIsStreaming(true);
76
+ };
77
+
78
+ return (
79
+ <Block
80
+ style={{
81
+ background: token.colorBgContainerSecondary,
82
+ marginBlock: 16,
83
+ minHeight: 280,
84
+ paddingBottom: 16,
85
+ }}
86
+ >
87
+ <ChatItem
88
+ actions={
89
+ <ActionIconGroup
90
+ items={[
91
+ {
92
+ icon: RotateCwIcon,
93
+ key: 'reset',
94
+ onClick: handleReset,
95
+ title: t('retry'),
96
+ },
97
+ ]}
98
+ size="small"
99
+ />
100
+ }
101
+ avatar={{ avatar: DEFAULT_INBOX_AVATAR }}
102
+ markdownProps={{ animated: mode === 'fadeIn' }}
103
+ message={streamedContent}
104
+ variant="bubble"
105
+ width={'100%'}
106
+ />
107
+ </Block>
108
+ );
109
+ });
110
+
111
+ export default ChatTransitionPreview;
@@ -4,14 +4,16 @@ import {
4
4
  Form,
5
5
  type FormGroupItemType,
6
6
  Icon,
7
+ Segmented,
7
8
  Select,
8
9
  SliderWithInput,
9
10
  highlighterThemes,
10
11
  mermaidThemes,
11
12
  } from '@lobehub/ui';
12
13
  import { Skeleton } from 'antd';
14
+ import { useTheme } from 'antd-style';
13
15
  import isEqual from 'fast-deep-equal';
14
- import { Loader2Icon } from 'lucide-react';
16
+ import { Loader2Icon, TriangleAlert } from 'lucide-react';
15
17
  import { memo, useState } from 'react';
16
18
  import { useTranslation } from 'react-i18next';
17
19
 
@@ -20,19 +22,64 @@ import { useUserStore } from '@/store/user';
20
22
  import { settingsSelectors } from '@/store/user/selectors';
21
23
 
22
24
  import ChatPreview from './ChatPreview';
25
+ import ChatTransitionPreview from './ChatTransitionPreview';
23
26
  import HighlighterPreview from './HighlighterPreview';
24
27
  import MermaidPreview from './MermaidPreview';
25
28
 
26
29
  const ChatAppearance = memo(() => {
27
30
  const { t } = useTranslation('setting');
28
31
  const { general } = useUserStore(settingsSelectors.currentSettings, isEqual);
32
+ const theme = useTheme();
29
33
  const [setSettings, isUserStateInit] = useUserStore((s) => [s.setSettings, s.isUserStateInit]);
30
34
  const [loading, setLoading] = useState(false);
31
35
 
32
36
  if (!isUserStateInit) return <Skeleton active paragraph={{ rows: 5 }} title={false} />;
33
37
 
34
- const theme: FormGroupItemType = {
38
+ const themeItems: FormGroupItemType = {
35
39
  children: [
40
+ {
41
+ children: (
42
+ <ChatTransitionPreview key={general.transitionMode} mode={general.transitionMode} />
43
+ ),
44
+ noStyle: true,
45
+ },
46
+ {
47
+ children: (
48
+ <Segmented
49
+ block
50
+ options={[
51
+ {
52
+ label: t('settingChatAppearance.transitionMode.options.none.value'),
53
+ value: 'none',
54
+ },
55
+ {
56
+ label: t('settingChatAppearance.transitionMode.options.fadeIn'),
57
+ value: 'fadeIn',
58
+ },
59
+ {
60
+ label: t('settingChatAppearance.transitionMode.options.smooth'),
61
+ value: 'smooth',
62
+ },
63
+ ]}
64
+ />
65
+ ),
66
+ desc: t('settingChatAppearance.transitionMode.desc'),
67
+ label: t('settingChatAppearance.transitionMode.title'),
68
+ name: 'transitionMode',
69
+ tooltip:
70
+ general.transitionMode === 'none'
71
+ ? {
72
+ icon: (
73
+ <TriangleAlert
74
+ color={theme.colorWarning}
75
+ size={14}
76
+ style={{ alignSelf: 'flex-end', marginBlockEnd: 2, marginInlineStart: 8 }}
77
+ />
78
+ ),
79
+ title: t('settingChatAppearance.transitionMode.options.none.desc'),
80
+ }
81
+ : undefined,
82
+ },
36
83
  {
37
84
  children: <ChatPreview fontSize={general.fontSize} />,
38
85
  noStyle: true,
@@ -112,7 +159,7 @@ const ChatAppearance = memo(() => {
112
159
  return (
113
160
  <Form
114
161
  initialValues={general}
115
- items={[theme]}
162
+ items={[themeItems]}
116
163
  itemsType={'group'}
117
164
  onValuesChange={async (value) => {
118
165
  setLoading(true);
@@ -77,9 +77,11 @@ interface ThinkingProps {
77
77
  duration?: number;
78
78
  style?: CSSProperties;
79
79
  thinking?: boolean;
80
+ thinkingAnimated?: boolean;
80
81
  }
81
82
 
82
- const Thinking = memo<ThinkingProps>(({ content, duration, thinking, style, citations }) => {
83
+ const Thinking = memo<ThinkingProps>((props) => {
84
+ const { content, duration, thinking, style, citations, thinkingAnimated } = props;
83
85
  const { t } = useTranslation(['components', 'common']);
84
86
  const { styles, cx, theme } = useStyles();
85
87
 
@@ -154,7 +156,7 @@ const Thinking = memo<ThinkingProps>(({ content, duration, thinking, style, cita
154
156
  }}
155
157
  >
156
158
  {typeof content === 'string' ? (
157
- <Markdown animated={thinking} citations={citations} variant={'chat'}>
159
+ <Markdown animated={thinkingAnimated} citations={citations} variant={'chat'}>
158
160
  {content}
159
161
  </Markdown>
160
162
  ) : (
@@ -196,14 +196,9 @@ const Anthropic: ModelProviderCard = {
196
196
  proxyUrl: {
197
197
  placeholder: 'https://api.anthropic.com',
198
198
  },
199
+ responseAnimation: 'smooth',
199
200
  sdkType: 'anthropic',
200
201
  showModelFetcher: true,
201
- smoothing: {
202
- text: true,
203
- },
204
- },
205
- smoothing: {
206
- text: true,
207
202
  },
208
203
  url: 'https://anthropic.com',
209
204
  };