@lobehub/chat 1.31.9 → 1.31.11
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 +42 -0
- package/locales/ar/error.json +1 -0
- package/locales/ar/models.json +3 -9
- package/locales/bg-BG/error.json +1 -0
- package/locales/bg-BG/models.json +3 -9
- package/locales/de-DE/error.json +1 -0
- package/locales/de-DE/models.json +3 -9
- package/locales/en-US/error.json +1 -0
- package/locales/en-US/models.json +3 -9
- package/locales/es-ES/error.json +1 -0
- package/locales/es-ES/models.json +4 -10
- package/locales/fa-IR/error.json +1 -0
- package/locales/fa-IR/models.json +3 -9
- package/locales/fr-FR/error.json +1 -0
- package/locales/fr-FR/models.json +4 -10
- package/locales/it-IT/error.json +1 -0
- package/locales/it-IT/models.json +3 -9
- package/locales/ja-JP/error.json +1 -0
- package/locales/ja-JP/models.json +3 -9
- package/locales/ko-KR/error.json +1 -0
- package/locales/ko-KR/models.json +3 -9
- package/locales/nl-NL/error.json +1 -0
- package/locales/nl-NL/models.json +3 -9
- package/locales/pl-PL/error.json +1 -0
- package/locales/pl-PL/models.json +4 -10
- package/locales/pt-BR/error.json +1 -0
- package/locales/pt-BR/models.json +3 -9
- package/locales/ru-RU/error.json +1 -0
- package/locales/ru-RU/models.json +3 -9
- package/locales/tr-TR/error.json +1 -0
- package/locales/tr-TR/models.json +3 -9
- package/locales/vi-VN/error.json +1 -0
- package/locales/vi-VN/models.json +3 -9
- package/locales/zh-CN/error.json +2 -1
- package/locales/zh-CN/models.json +3 -9
- package/locales/zh-TW/error.json +1 -0
- package/locales/zh-TW/models.json +3 -9
- package/package.json +3 -3
- package/src/{features → app/(main)/chat/(workspace)/@conversation/features}/ChatInput/Desktop/TextArea.test.tsx +13 -13
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/TextArea.tsx +29 -0
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/index.tsx +46 -0
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/index.tsx +2 -1
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatList/Content.tsx +13 -11
- package/src/app/(main)/settings/llm/components/Checker.tsx +9 -2
- package/src/const/message.ts +4 -0
- package/src/features/ChatInput/Desktop/Footer/ShortcutHint.tsx +61 -0
- package/src/features/ChatInput/Desktop/Footer/index.tsx +11 -46
- package/src/features/ChatInput/Desktop/{TextArea.tsx → InputArea/index.tsx} +11 -20
- package/src/features/ChatInput/Desktop/index.tsx +23 -32
- package/src/features/Conversation/Messages/index.ts +11 -11
- package/src/features/Conversation/components/ChatItem/index.tsx +83 -44
- package/src/features/Conversation/components/VirtualizedList/index.tsx +90 -92
- package/src/features/Conversation/index.ts +2 -0
- package/src/libs/agent-runtime/error.ts +2 -0
- package/src/locales/default/error.ts +1 -0
- package/src/types/topic/index.ts +1 -0
- /package/src/types/{topic.ts → topic/topic.ts} +0 -0
package/locales/ru-RU/error.json
CHANGED
@@ -68,6 +68,7 @@
|
|
68
68
|
"510": "Извините, сервер не поддерживает запрашиваемую расширенную функцию. Пожалуйста, свяжитесь с администратором.",
|
69
69
|
"524": "Извините, сервер превысил время ожидания ответа, возможно, из-за слишком медленного ответа. Пожалуйста, попробуйте позже.",
|
70
70
|
"AgentRuntimeError": "Ошибка выполнения времени выполнения языковой модели Lobe, пожалуйста, проверьте и повторите попытку в соответствии с предоставленной информацией",
|
71
|
+
"ConnectionCheckFailed": "Запрос вернул пустой ответ, пожалуйста, проверьте, что в конце адреса API-прокси не указано `/v1`",
|
71
72
|
"FreePlanLimit": "Вы являетесь бесплатным пользователем и не можете использовать эту функцию. Пожалуйста, перейдите на платный план для продолжения использования.",
|
72
73
|
"InvalidAccessCode": "Неверный код доступа: введите правильный код доступа или добавьте пользовательский ключ API",
|
73
74
|
"InvalidBedrockCredentials": "Аутентификация Bedrock не прошла, пожалуйста, проверьте AccessKeyId/SecretAccessKey и повторите попытку",
|
@@ -460,9 +460,6 @@
|
|
460
460
|
"gemini-1.5-flash-8b-exp-0924": {
|
461
461
|
"description": "Gemini 1.5 Flash 8B 0924 — это последняя экспериментальная модель, которая демонстрирует значительное улучшение производительности как в текстовых, так и в мультимодальных задачах."
|
462
462
|
},
|
463
|
-
"gemini-1.5-flash-exp-0827": {
|
464
|
-
"description": "Gemini 1.5 Flash 0827 предлагает оптимизированные многомодальные возможности обработки, подходящие для различных сложных задач."
|
465
|
-
},
|
466
463
|
"gemini-1.5-flash-latest": {
|
467
464
|
"description": "Gemini 1.5 Flash — это последняя многомодальная модель ИИ от Google, обладающая высокой скоростью обработки и поддерживающая текстовые, графические и видео входы, что делает её эффективной для масштабирования различных задач."
|
468
465
|
},
|
@@ -472,15 +469,12 @@
|
|
472
469
|
"gemini-1.5-pro-002": {
|
473
470
|
"description": "Gemini 1.5 Pro 002 — это последняя модель, готовая к производству, которая обеспечивает более высокое качество вывода, особенно в математических задачах, длинных контекстах и визуальных задачах."
|
474
471
|
},
|
475
|
-
"gemini-1.5-pro-exp-0801": {
|
476
|
-
"description": "Gemini 1.5 Pro 0801 предлагает выдающиеся возможности многомодальной обработки, обеспечивая большую гибкость для разработки приложений."
|
477
|
-
},
|
478
|
-
"gemini-1.5-pro-exp-0827": {
|
479
|
-
"description": "Gemini 1.5 Pro 0827 сочетает в себе новейшие оптимизационные технологии, обеспечивая более эффективные возможности обработки многомодальных данных."
|
480
|
-
},
|
481
472
|
"gemini-1.5-pro-latest": {
|
482
473
|
"description": "Gemini 1.5 Pro поддерживает до 2 миллионов токенов и является идеальным выбором для средних многомодальных моделей, обеспечивая многостороннюю поддержку для сложных задач."
|
483
474
|
},
|
475
|
+
"gemini-exp-1114": {
|
476
|
+
"description": "Gemini Exp 1114 — это новейшая экспериментальная многомодальная ИИ модель от Google, обладающая высокой скоростью обработки и поддерживающая текстовые, изображенческие и видеовходы, что позволяет эффективно расширять применение для различных задач."
|
477
|
+
},
|
484
478
|
"gemma-7b-it": {
|
485
479
|
"description": "Gemma 7B подходит для обработки задач среднего и малого масштаба, обеспечивая экономическую эффективность."
|
486
480
|
},
|
package/locales/tr-TR/error.json
CHANGED
@@ -68,6 +68,7 @@
|
|
68
68
|
"510": "Üzgünüm, sunucu isteğinizi genişletme işlevini desteklemiyor, lütfen yöneticinizle iletişime geçin",
|
69
69
|
"524": "Üzgünüm, sunucu yanıt beklerken zaman aşımına uğradı, bu muhtemelen yanıtın çok yavaş olmasından kaynaklanıyor, lütfen daha sonra tekrar deneyin",
|
70
70
|
"AgentRuntimeError": "Lobe dil modeli çalışma zamanı hatası, lütfen aşağıdaki bilgilere göre sorunu gidermeye çalışın veya tekrar deneyin",
|
71
|
+
"ConnectionCheckFailed": "İstek boş döndü, lütfen API代理地址ının sonuna `/v1` ekleyip eklemediğinizi kontrol edin.",
|
71
72
|
"FreePlanLimit": "Şu anda ücretsiz bir kullanıcısınız, bu özelliği kullanamazsınız. Lütfen devam etmek için bir ücretli plana yükseltin.",
|
72
73
|
"InvalidAccessCode": "Geçersiz Erişim Kodu: Geçersiz veya boş bir şifre girdiniz. Lütfen doğru erişim şifresini girin veya özel API Anahtarı ekleyin.",
|
73
74
|
"InvalidBedrockCredentials": "Bedrock kimlik doğrulaması geçersiz, lütfen AccessKeyId/SecretAccessKey bilgilerinizi kontrol edip tekrar deneyin",
|
@@ -460,9 +460,6 @@
|
|
460
460
|
"gemini-1.5-flash-8b-exp-0924": {
|
461
461
|
"description": "Gemini 1.5 Flash 8B 0924, metin ve çok modlu kullanım durumlarında önemli performans artışları sunan en son deneysel modeldir."
|
462
462
|
},
|
463
|
-
"gemini-1.5-flash-exp-0827": {
|
464
|
-
"description": "Gemini 1.5 Flash 0827, çeşitli karmaşık görev senaryoları için optimize edilmiş çok modlu işleme yeteneği sunar."
|
465
|
-
},
|
466
463
|
"gemini-1.5-flash-latest": {
|
467
464
|
"description": "Gemini 1.5 Flash, Google'ın en son çok modlu AI modelidir, hızlı işleme yeteneğine sahiptir ve metin, görüntü ve video girişi destekler, çeşitli görevlerin verimli bir şekilde genişletilmesine olanak tanır."
|
468
465
|
},
|
@@ -472,15 +469,12 @@
|
|
472
469
|
"gemini-1.5-pro-002": {
|
473
470
|
"description": "Gemini 1.5 Pro 002, daha yüksek kaliteli çıktılar sunan en son üretim hazır modeldir; özellikle matematik, uzun bağlam ve görsel görevlerde önemli iyileştirmeler sağlamaktadır."
|
474
471
|
},
|
475
|
-
"gemini-1.5-pro-exp-0801": {
|
476
|
-
"description": "Gemini 1.5 Pro 0801, mükemmel çok modlu işleme yeteneği sunar ve uygulama geliştirmeye daha fazla esneklik kazandırır."
|
477
|
-
},
|
478
|
-
"gemini-1.5-pro-exp-0827": {
|
479
|
-
"description": "Gemini 1.5 Pro 0827, en son optimize edilmiş teknolojileri bir araya getirerek daha verimli çok modlu veri işleme yeteneği sunar."
|
480
|
-
},
|
481
472
|
"gemini-1.5-pro-latest": {
|
482
473
|
"description": "Gemini 1.5 Pro, 2 milyon token'a kadar destekler, orta ölçekli çok modlu modeller için ideal bir seçimdir ve karmaşık görevler için çok yönlü destek sunar."
|
483
474
|
},
|
475
|
+
"gemini-exp-1114": {
|
476
|
+
"description": "Gemini Exp 1114, Google'ın en son deneysel çok modlu AI modeli olup, hızlı işleme yeteneğine sahip, metin, görüntü ve video girişlerini desteklemekte ve çeşitli görevlerde verimli bir şekilde ölçeklenmektedir."
|
477
|
+
},
|
484
478
|
"gemma-7b-it": {
|
485
479
|
"description": "Gemma 7B, orta ölçekli görev işleme için uygundur ve maliyet etkinliği sunar."
|
486
480
|
},
|
package/locales/vi-VN/error.json
CHANGED
@@ -68,6 +68,7 @@
|
|
68
68
|
"510": "Xin lỗi, máy chủ không hỗ trợ chức năng mở rộng được yêu cầu, vui lòng liên hệ với quản trị viên",
|
69
69
|
"524": "Xin lỗi, máy chủ đã hết thời gian chờ khi đang chờ phản hồi, có thể do phản hồi quá chậm, vui lòng thử lại sau",
|
70
70
|
"AgentRuntimeError": "Lobe mô hình ngôn ngữ thực thi gặp lỗi, vui lòng kiểm tra và thử lại dựa trên thông tin dưới đây",
|
71
|
+
"ConnectionCheckFailed": "Yêu cầu trả về trống, xin kiểm tra xem địa chỉ API proxy có đang thiếu `/v1` ở cuối không",
|
71
72
|
"FreePlanLimit": "Hiện tại bạn đang sử dụng tài khoản miễn phí, không thể sử dụng tính năng này. Vui lòng nâng cấp lên gói trả phí để tiếp tục sử dụng.",
|
72
73
|
"InvalidAccessCode": "Mật khẩu truy cập không hợp lệ hoặc trống, vui lòng nhập mật khẩu truy cập đúng hoặc thêm Khóa API tùy chỉnh",
|
73
74
|
"InvalidBedrockCredentials": "Xác thực Bedrock không thành công, vui lòng kiểm tra AccessKeyId/SecretAccessKey và thử lại",
|
@@ -460,9 +460,6 @@
|
|
460
460
|
"gemini-1.5-flash-8b-exp-0924": {
|
461
461
|
"description": "Gemini 1.5 Flash 8B 0924 là mô hình thử nghiệm mới nhất, có sự cải thiện đáng kể về hiệu suất trong các trường hợp sử dụng văn bản và đa phương thức."
|
462
462
|
},
|
463
|
-
"gemini-1.5-flash-exp-0827": {
|
464
|
-
"description": "Gemini 1.5 Flash 0827 cung cấp khả năng xử lý đa phương thức được tối ưu hóa, phù hợp cho nhiều tình huống nhiệm vụ phức tạp."
|
465
|
-
},
|
466
463
|
"gemini-1.5-flash-latest": {
|
467
464
|
"description": "Gemini 1.5 Flash là mô hình AI đa phương thức mới nhất của Google, có khả năng xử lý nhanh, hỗ trợ đầu vào văn bản, hình ảnh và video, phù hợp cho việc mở rộng hiệu quả cho nhiều nhiệm vụ."
|
468
465
|
},
|
@@ -472,15 +469,12 @@
|
|
472
469
|
"gemini-1.5-pro-002": {
|
473
470
|
"description": "Gemini 1.5 Pro 002 là mô hình sẵn sàng cho sản xuất mới nhất, cung cấp đầu ra chất lượng cao hơn, đặc biệt là trong các nhiệm vụ toán học, ngữ cảnh dài và thị giác."
|
474
471
|
},
|
475
|
-
"gemini-1.5-pro-exp-0801": {
|
476
|
-
"description": "Gemini 1.5 Pro 0801 cung cấp khả năng xử lý đa phương thức xuất sắc, mang lại sự linh hoạt lớn hơn cho phát triển ứng dụng."
|
477
|
-
},
|
478
|
-
"gemini-1.5-pro-exp-0827": {
|
479
|
-
"description": "Gemini 1.5 Pro 0827 kết hợp công nghệ tối ưu hóa mới nhất, mang lại khả năng xử lý dữ liệu đa phương thức hiệu quả hơn."
|
480
|
-
},
|
481
472
|
"gemini-1.5-pro-latest": {
|
482
473
|
"description": "Gemini 1.5 Pro hỗ trợ lên đến 2 triệu tokens, là lựa chọn lý tưởng cho mô hình đa phương thức trung bình, phù hợp cho hỗ trợ đa diện cho các nhiệm vụ phức tạp."
|
483
474
|
},
|
475
|
+
"gemini-exp-1114": {
|
476
|
+
"description": "Gemini Exp 1114 là mô hình AI đa phương thức thử nghiệm mới nhất của Google, có khả năng xử lý nhanh, hỗ trợ đầu vào văn bản, hình ảnh và video, phù hợp với việc mở rộng hiệu quả cho nhiều nhiệm vụ."
|
477
|
+
},
|
484
478
|
"gemma-7b-it": {
|
485
479
|
"description": "Gemma 7B phù hợp cho việc xử lý các nhiệm vụ quy mô vừa và nhỏ, đồng thời mang lại hiệu quả chi phí."
|
486
480
|
},
|
package/locales/zh-CN/error.json
CHANGED
@@ -98,7 +98,8 @@
|
|
98
98
|
"AgentRuntimeError": "Lobe AI Runtime 执行出错,请根据以下信息排查或重试",
|
99
99
|
"FreePlanLimit": "当前为免费用户,无法使用该功能,请升级到付费计划后继续使用",
|
100
100
|
"SubscriptionPlanLimit": "您的订阅额度已用尽,无法使用该功能,请升级到更高计划,或购买资源包后继续使用",
|
101
|
-
"InvalidGithubToken": "Github PAT 不正确或为空,请检查 Github PAT 后重试"
|
101
|
+
"InvalidGithubToken": "Github PAT 不正确或为空,请检查 Github PAT 后重试",
|
102
|
+
"ConnectionCheckFailed": "请求返回为空,请检查 API 代理地址末尾是否未包含 `/v1`"
|
102
103
|
},
|
103
104
|
"stt": {
|
104
105
|
"responseError": "服务请求失败,请检查配置或重试"
|
@@ -460,9 +460,6 @@
|
|
460
460
|
"gemini-1.5-flash-8b-exp-0924": {
|
461
461
|
"description": "Gemini 1.5 Flash 8B 0924 是最新的实验性模型,在文本和多模态用例中都有显著的性能提升。"
|
462
462
|
},
|
463
|
-
"gemini-1.5-flash-exp-0827": {
|
464
|
-
"description": "Gemini 1.5 Flash 0827 提供了优化后的多模态处理能力,适用多种复杂任务场景。"
|
465
|
-
},
|
466
463
|
"gemini-1.5-flash-latest": {
|
467
464
|
"description": "Gemini 1.5 Flash 是Google最新的多模态AI模型,具备快速处理能力,支持文本、图像和视频输入,适用于多种任务的高效扩展。"
|
468
465
|
},
|
@@ -472,15 +469,12 @@
|
|
472
469
|
"gemini-1.5-pro-002": {
|
473
470
|
"description": "Gemini 1.5 Pro 002 是最新的生产就绪模型,提供更高质量的输出,特别在数学、长上下文和视觉任务方面有显著提升。"
|
474
471
|
},
|
475
|
-
"gemini-1.5-pro-exp-0801": {
|
476
|
-
"description": "Gemini 1.5 Pro 0801 提供出色的多模态处理能力,为应用开发带来更大灵活性。"
|
477
|
-
},
|
478
|
-
"gemini-1.5-pro-exp-0827": {
|
479
|
-
"description": "Gemini 1.5 Pro 0827 结合最新优化技术,带来更高效的多模态数据处理能力。"
|
480
|
-
},
|
481
472
|
"gemini-1.5-pro-latest": {
|
482
473
|
"description": "Gemini 1.5 Pro 支持高达200万个tokens,是中型多模态模型的理想选择,适用于复杂任务的多方面支持。"
|
483
474
|
},
|
475
|
+
"gemini-exp-1114": {
|
476
|
+
"description": "Gemini Exp 1114 是Google最新的实验性多模态AI模型,具备快速处理能力,支持文本、图像和视频输入,适用于多种任务的高效扩展。"
|
477
|
+
},
|
484
478
|
"gemma-7b-it": {
|
485
479
|
"description": "Gemma 7B 适合中小规模任务处理,兼具成本效益。"
|
486
480
|
},
|
package/locales/zh-TW/error.json
CHANGED
@@ -68,6 +68,7 @@
|
|
68
68
|
"510": "很抱歉,伺服器不支援請求的擴展功能,請聯繫管理員",
|
69
69
|
"524": "很抱歉,伺服器在等待回覆時超時,可能是因為回應太慢,請稍後再試",
|
70
70
|
"AgentRuntimeError": "Lobe 語言模型運行時執行出錯,請根據以下信息排查或重試",
|
71
|
+
"ConnectionCheckFailed": "請求返回為空,請檢查 API 代理地址末尾是否未包含 `/v1`",
|
71
72
|
"FreePlanLimit": "目前為免費用戶,無法使用該功能,請升級到付費計劃後繼續使用",
|
72
73
|
"InvalidAccessCode": "密碼不正確或為空,請輸入正確的訪問密碼,或添加自定義 API 金鑰",
|
73
74
|
"InvalidBedrockCredentials": "Bedrock 驗證未通過,請檢查 AccessKeyId/SecretAccessKey 後重試",
|
@@ -460,9 +460,6 @@
|
|
460
460
|
"gemini-1.5-flash-8b-exp-0924": {
|
461
461
|
"description": "Gemini 1.5 Flash 8B 0924 是最新的實驗性模型,在文本和多模態用例中都有顯著的性能提升。"
|
462
462
|
},
|
463
|
-
"gemini-1.5-flash-exp-0827": {
|
464
|
-
"description": "Gemini 1.5 Flash 0827 提供了優化後的多模態處理能力,適用多種複雜任務場景。"
|
465
|
-
},
|
466
463
|
"gemini-1.5-flash-latest": {
|
467
464
|
"description": "Gemini 1.5 Flash 是 Google 最新的多模態 AI 模型,具備快速處理能力,支持文本、圖像和視頻輸入,適用於多種任務的高效擴展。"
|
468
465
|
},
|
@@ -472,15 +469,12 @@
|
|
472
469
|
"gemini-1.5-pro-002": {
|
473
470
|
"description": "Gemini 1.5 Pro 002 是最新的生產就緒模型,提供更高品質的輸出,特別在數學、長上下文和視覺任務方面有顯著提升。"
|
474
471
|
},
|
475
|
-
"gemini-1.5-pro-exp-0801": {
|
476
|
-
"description": "Gemini 1.5 Pro 0801 提供出色的多模態處理能力,為應用開發帶來更大靈活性。"
|
477
|
-
},
|
478
|
-
"gemini-1.5-pro-exp-0827": {
|
479
|
-
"description": "Gemini 1.5 Pro 0827 結合最新優化技術,帶來更高效的多模態數據處理能力。"
|
480
|
-
},
|
481
472
|
"gemini-1.5-pro-latest": {
|
482
473
|
"description": "Gemini 1.5 Pro 支持高達 200 萬個 tokens,是中型多模態模型的理想選擇,適用於複雜任務的多方面支持。"
|
483
474
|
},
|
475
|
+
"gemini-exp-1114": {
|
476
|
+
"description": "Gemini Exp 1114 是 Google 最新的實驗性多模態 AI 模型,具備快速處理能力,支持文本、影像和影片輸入,適用於多種任務的高效擴展。"
|
477
|
+
},
|
484
478
|
"gemma-7b-it": {
|
485
479
|
"description": "Gemma 7B 適合中小規模任務處理,兼具成本效益。"
|
486
480
|
},
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.31.
|
3
|
+
"version": "1.31.11",
|
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",
|
@@ -110,7 +110,7 @@
|
|
110
110
|
"@azure/core-rest-pipeline": "1.16.0",
|
111
111
|
"@azure/openai": "1.0.0-beta.12",
|
112
112
|
"@baiducloud/qianfan": "^0.1.9",
|
113
|
-
"@cfworker/json-schema": "^
|
113
|
+
"@cfworker/json-schema": "^3.0.0",
|
114
114
|
"@clerk/localizations": "^3.3.0",
|
115
115
|
"@clerk/nextjs": "^5.7.5",
|
116
116
|
"@clerk/themes": "^2.1.37",
|
@@ -302,7 +302,7 @@
|
|
302
302
|
"vitest": "~1.2.2",
|
303
303
|
"vitest-canvas-mock": "^0.3.3"
|
304
304
|
},
|
305
|
-
"packageManager": "pnpm@9.
|
305
|
+
"packageManager": "pnpm@9.13.2",
|
306
306
|
"publishConfig": {
|
307
307
|
"access": "public",
|
308
308
|
"registry": "https://registry.npmjs.org"
|
@@ -7,10 +7,10 @@ import { useUserStore } from '@/store/user';
|
|
7
7
|
|
8
8
|
import InputArea from './TextArea';
|
9
9
|
|
10
|
-
let
|
10
|
+
let onSendMock: () => void;
|
11
11
|
|
12
12
|
beforeEach(() => {
|
13
|
-
|
13
|
+
onSendMock = vi.fn();
|
14
14
|
});
|
15
15
|
|
16
16
|
describe('<InputArea />', () => {
|
@@ -29,13 +29,13 @@ describe('<InputArea />', () => {
|
|
29
29
|
});
|
30
30
|
|
31
31
|
it('renders with correct placeholder text', () => {
|
32
|
-
render(<InputArea
|
32
|
+
render(<InputArea onSend={onSendMock} />);
|
33
33
|
const textArea = screen.getByPlaceholderText('sendPlaceholder');
|
34
34
|
expect(textArea).toBeInTheDocument();
|
35
35
|
});
|
36
36
|
|
37
37
|
it('has the correct initial value', () => {
|
38
|
-
render(<InputArea
|
38
|
+
render(<InputArea onSend={onSendMock} />);
|
39
39
|
const textArea = screen.getByRole('textbox');
|
40
40
|
expect(textArea).toHaveValue('');
|
41
41
|
});
|
@@ -82,7 +82,7 @@ describe('<InputArea />', () => {
|
|
82
82
|
useChatStore.setState({ updateInputMessage: updateInputMessageMock });
|
83
83
|
});
|
84
84
|
|
85
|
-
render(<InputArea
|
85
|
+
render(<InputArea onSend={onSendMock} />);
|
86
86
|
const textArea = screen.getByRole('textbox');
|
87
87
|
|
88
88
|
// Start composition (IME input starts)
|
@@ -92,7 +92,7 @@ describe('<InputArea />', () => {
|
|
92
92
|
fireEvent.keyDown(textArea, { code: 'Enter', key: 'Enter' });
|
93
93
|
|
94
94
|
// Since we are in the middle of IME composition, the message should not be sent
|
95
|
-
expect(
|
95
|
+
expect(onSendMock).not.toHaveBeenCalled();
|
96
96
|
expect(updateInputMessageMock).not.toHaveBeenCalled();
|
97
97
|
|
98
98
|
// End composition (IME input ends)
|
@@ -102,7 +102,7 @@ describe('<InputArea />', () => {
|
|
102
102
|
fireEvent.keyDown(textArea, { code: 'Enter', key: 'Enter' });
|
103
103
|
|
104
104
|
// Since IME composition has ended, now the message should be sent
|
105
|
-
expect(
|
105
|
+
expect(onSendMock).toHaveBeenCalled();
|
106
106
|
expect(updateInputMessageMock).toHaveBeenCalled();
|
107
107
|
});
|
108
108
|
|
@@ -112,7 +112,7 @@ describe('<InputArea />', () => {
|
|
112
112
|
useChatStore.setState({ updateInputMessage: updateInputMessageMock });
|
113
113
|
});
|
114
114
|
|
115
|
-
render(<InputArea
|
115
|
+
render(<InputArea onSend={onSendMock} />);
|
116
116
|
const textArea = screen.getByRole('textbox');
|
117
117
|
const newText = 'New input text';
|
118
118
|
|
@@ -199,7 +199,7 @@ describe('<InputArea />', () => {
|
|
199
199
|
useChatStore.setState({ chatLoadingIds: ['123'], sendMessage: sendMessageMock });
|
200
200
|
});
|
201
201
|
|
202
|
-
render(<InputArea
|
202
|
+
render(<InputArea onSend={onSendMock} />);
|
203
203
|
const textArea = screen.getByRole('textbox');
|
204
204
|
|
205
205
|
fireEvent.keyDown(textArea, { code: 'Enter', key: 'Enter', shiftKey: true });
|
@@ -236,7 +236,7 @@ describe('<InputArea />', () => {
|
|
236
236
|
useUserStore.getState().updatePreference({ useCmdEnterToSend: true });
|
237
237
|
});
|
238
238
|
|
239
|
-
render(<InputArea
|
239
|
+
render(<InputArea onSend={onSendMock} />);
|
240
240
|
const textArea = screen.getByRole('textbox');
|
241
241
|
|
242
242
|
fireEvent.keyDown(textArea, { code: 'Enter', ctrlKey: true, key: 'Enter' });
|
@@ -256,7 +256,7 @@ describe('<InputArea />', () => {
|
|
256
256
|
useUserStore.getState().updatePreference({ useCmdEnterToSend: false });
|
257
257
|
});
|
258
258
|
|
259
|
-
render(<InputArea
|
259
|
+
render(<InputArea onSend={onSendMock} />);
|
260
260
|
const textArea = screen.getByRole('textbox');
|
261
261
|
|
262
262
|
fireEvent.keyDown(textArea, { code: 'Enter', ctrlKey: true, key: 'Enter' });
|
@@ -279,7 +279,7 @@ describe('<InputArea />', () => {
|
|
279
279
|
useUserStore.getState().updatePreference({ useCmdEnterToSend: true });
|
280
280
|
});
|
281
281
|
|
282
|
-
render(<InputArea
|
282
|
+
render(<InputArea onSend={onSendMock} />);
|
283
283
|
const textArea = screen.getByRole('textbox');
|
284
284
|
|
285
285
|
fireEvent.keyDown(textArea, { code: 'Enter', key: 'Enter', metaKey: true });
|
@@ -304,7 +304,7 @@ describe('<InputArea />', () => {
|
|
304
304
|
useUserStore.getState().updatePreference({ useCmdEnterToSend: false });
|
305
305
|
});
|
306
306
|
|
307
|
-
render(<InputArea
|
307
|
+
render(<InputArea onSend={onSendMock} />);
|
308
308
|
const textArea = screen.getByRole('textbox');
|
309
309
|
|
310
310
|
fireEvent.keyDown(textArea, { code: 'Enter', key: 'Enter', metaKey: true });
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import { memo } from 'react';
|
2
|
+
|
3
|
+
import InputArea from '@/features/ChatInput/Desktop/InputArea';
|
4
|
+
import { useSendMessage } from '@/features/ChatInput/useSend';
|
5
|
+
import { useChatStore } from '@/store/chat';
|
6
|
+
import { chatSelectors } from '@/store/chat/slices/message/selectors';
|
7
|
+
|
8
|
+
const TextArea = memo<{ onSend?: () => void }>(({ onSend }) => {
|
9
|
+
const [loading, value, updateInputMessage] = useChatStore((s) => [
|
10
|
+
chatSelectors.isAIGenerating(s),
|
11
|
+
s.inputMessage,
|
12
|
+
s.updateInputMessage,
|
13
|
+
]);
|
14
|
+
const { send: sendMessage } = useSendMessage();
|
15
|
+
|
16
|
+
return (
|
17
|
+
<InputArea
|
18
|
+
loading={loading}
|
19
|
+
onChange={updateInputMessage}
|
20
|
+
onSend={() => {
|
21
|
+
sendMessage();
|
22
|
+
onSend?.();
|
23
|
+
}}
|
24
|
+
value={value}
|
25
|
+
/>
|
26
|
+
);
|
27
|
+
});
|
28
|
+
|
29
|
+
export default TextArea;
|
@@ -0,0 +1,46 @@
|
|
1
|
+
'use client';
|
2
|
+
|
3
|
+
import { memo } from 'react';
|
4
|
+
|
5
|
+
import { ActionKeys } from '@/features/ChatInput/ActionBar/config';
|
6
|
+
import DesktopChatInput from '@/features/ChatInput/Desktop';
|
7
|
+
import { useGlobalStore } from '@/store/global';
|
8
|
+
import { systemStatusSelectors } from '@/store/global/selectors';
|
9
|
+
|
10
|
+
import TextArea from './TextArea';
|
11
|
+
|
12
|
+
const leftActions = [
|
13
|
+
'model',
|
14
|
+
'fileUpload',
|
15
|
+
'knowledgeBase',
|
16
|
+
'temperature',
|
17
|
+
'history',
|
18
|
+
'stt',
|
19
|
+
'tools',
|
20
|
+
'token',
|
21
|
+
] as ActionKeys[];
|
22
|
+
|
23
|
+
const rightActions = ['clear'] as ActionKeys[];
|
24
|
+
|
25
|
+
const renderTextArea = (onSend: () => void) => <TextArea onSend={onSend} />;
|
26
|
+
|
27
|
+
const Desktop = memo(() => {
|
28
|
+
const [inputHeight, updatePreference] = useGlobalStore((s) => [
|
29
|
+
systemStatusSelectors.inputHeight(s),
|
30
|
+
s.updateSystemStatus,
|
31
|
+
]);
|
32
|
+
|
33
|
+
return (
|
34
|
+
<DesktopChatInput
|
35
|
+
inputHeight={inputHeight}
|
36
|
+
leftActions={leftActions}
|
37
|
+
onInputHeightChange={(height) => {
|
38
|
+
updatePreference({ inputHeight: height });
|
39
|
+
}}
|
40
|
+
renderTextArea={renderTextArea}
|
41
|
+
rightActions={rightActions}
|
42
|
+
/>
|
43
|
+
);
|
44
|
+
});
|
45
|
+
|
46
|
+
export default Desktop;
|
@@ -1,7 +1,8 @@
|
|
1
|
-
import DesktopChatInput from '@/features/ChatInput/Desktop';
|
2
1
|
import MobileChatInput from '@/features/ChatInput/Mobile';
|
3
2
|
import { isMobileDevice } from '@/utils/server/responsive';
|
4
3
|
|
4
|
+
import DesktopChatInput from './Desktop';
|
5
|
+
|
5
6
|
const ChatInput = () => {
|
6
7
|
const mobile = isMobileDevice();
|
7
8
|
const Input = mobile ? MobileChatInput : DesktopChatInput;
|
@@ -3,8 +3,7 @@
|
|
3
3
|
import isEqual from 'fast-deep-equal';
|
4
4
|
import React, { memo } from 'react';
|
5
5
|
|
6
|
-
import {
|
7
|
-
import { VirtualizedList } from '@/features/Conversation';
|
6
|
+
import { InboxWelcome, VirtualizedList } from '@/features/Conversation';
|
8
7
|
import { useChatStore } from '@/store/chat';
|
9
8
|
import { chatSelectors } from '@/store/chat/selectors';
|
10
9
|
import { useSessionStore } from '@/store/session';
|
@@ -14,22 +13,25 @@ interface ListProps {
|
|
14
13
|
}
|
15
14
|
|
16
15
|
const Content = memo<ListProps>(({ mobile }) => {
|
17
|
-
const [activeTopicId, useFetchMessages] = useChatStore(
|
18
|
-
s
|
19
|
-
|
20
|
-
|
16
|
+
const [activeTopicId, useFetchMessages, showInboxWelcome, isCurrentChatLoaded] = useChatStore(
|
17
|
+
(s) => [
|
18
|
+
s.activeTopicId,
|
19
|
+
s.useFetchMessages,
|
20
|
+
chatSelectors.showInboxWelcome(s),
|
21
|
+
chatSelectors.isCurrentChatLoaded(s),
|
22
|
+
],
|
23
|
+
);
|
21
24
|
|
22
25
|
const [sessionId] = useSessionStore((s) => [s.activeId]);
|
23
26
|
useFetchMessages(sessionId, activeTopicId);
|
24
27
|
|
25
|
-
const data = useChatStore(
|
26
|
-
const showInboxWelcome = chatSelectors.showInboxWelcome(s);
|
27
|
-
if (showInboxWelcome) return [WELCOME_GUIDE_CHAT_ID];
|
28
|
+
const data = useChatStore(chatSelectors.currentChatIDsWithGuideMessage, isEqual);
|
28
29
|
|
29
|
-
|
30
|
-
}, isEqual);
|
30
|
+
if (showInboxWelcome && isCurrentChatLoaded) return <InboxWelcome />;
|
31
31
|
|
32
32
|
return <VirtualizedList dataSource={data} mobile={mobile} />;
|
33
33
|
});
|
34
34
|
|
35
|
+
Content.displayName = 'ChatListRender';
|
36
|
+
|
35
37
|
export default Content;
|
@@ -60,10 +60,17 @@ const Checker = memo<ConnectionCheckerProps>(({ model, provider }) => {
|
|
60
60
|
setPass(false);
|
61
61
|
isError = true;
|
62
62
|
},
|
63
|
-
onFinish: async () => {
|
64
|
-
if (!isError) {
|
63
|
+
onFinish: async (value) => {
|
64
|
+
if (!isError && value) {
|
65
65
|
setError(undefined);
|
66
66
|
setPass(true);
|
67
|
+
} else {
|
68
|
+
setPass(false);
|
69
|
+
setError({
|
70
|
+
body: value,
|
71
|
+
message: t('response.ConnectionCheckFailed', { ns: 'error' }),
|
72
|
+
type: 'ConnectionCheckFailed',
|
73
|
+
});
|
67
74
|
}
|
68
75
|
},
|
69
76
|
onLoadingChange: (loading) => {
|
package/src/const/message.ts
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
import { Icon } from '@lobehub/ui';
|
2
|
+
import { Skeleton } from 'antd';
|
3
|
+
import { useTheme } from 'antd-style';
|
4
|
+
import { ChevronUp, CornerDownLeft, LucideCommand } from 'lucide-react';
|
5
|
+
import { memo, useEffect, useState } from 'react';
|
6
|
+
import { useTranslation } from 'react-i18next';
|
7
|
+
import { Center, Flexbox } from 'react-layout-kit';
|
8
|
+
|
9
|
+
import { useUserStore } from '@/store/user';
|
10
|
+
import { preferenceSelectors } from '@/store/user/selectors';
|
11
|
+
import { isMacOS } from '@/utils/platform';
|
12
|
+
|
13
|
+
const ShortcutHint = memo(() => {
|
14
|
+
const { t } = useTranslation('chat');
|
15
|
+
const theme = useTheme();
|
16
|
+
const useCmdEnterToSend = useUserStore(preferenceSelectors.useCmdEnterToSend);
|
17
|
+
const [isMac, setIsMac] = useState<boolean>();
|
18
|
+
|
19
|
+
useEffect(() => {
|
20
|
+
setIsMac(isMacOS());
|
21
|
+
}, []);
|
22
|
+
|
23
|
+
const cmdEnter = (
|
24
|
+
<Flexbox gap={2} horizontal>
|
25
|
+
{typeof isMac === 'boolean' ? (
|
26
|
+
<Icon icon={isMac ? LucideCommand : ChevronUp} />
|
27
|
+
) : (
|
28
|
+
<Skeleton.Node active style={{ height: '100%', width: 12 }}>
|
29
|
+
{' '}
|
30
|
+
</Skeleton.Node>
|
31
|
+
)}
|
32
|
+
<Icon icon={CornerDownLeft} />
|
33
|
+
</Flexbox>
|
34
|
+
);
|
35
|
+
|
36
|
+
const enter = (
|
37
|
+
<Center>
|
38
|
+
<Icon icon={CornerDownLeft} />
|
39
|
+
</Center>
|
40
|
+
);
|
41
|
+
|
42
|
+
const sendShortcut = useCmdEnterToSend ? cmdEnter : enter;
|
43
|
+
|
44
|
+
const wrapperShortcut = useCmdEnterToSend ? enter : cmdEnter;
|
45
|
+
|
46
|
+
return (
|
47
|
+
<Flexbox
|
48
|
+
gap={4}
|
49
|
+
horizontal
|
50
|
+
style={{ color: theme.colorTextDescription, fontSize: 12, marginRight: 12 }}
|
51
|
+
>
|
52
|
+
{sendShortcut}
|
53
|
+
<span>{t('input.send')}</span>
|
54
|
+
<span>/</span>
|
55
|
+
{wrapperShortcut}
|
56
|
+
<span>{t('input.warp')}</span>
|
57
|
+
</Flexbox>
|
58
|
+
);
|
59
|
+
});
|
60
|
+
|
61
|
+
export default ShortcutHint;
|