@lobehub/chat 1.1.15 → 1.1.17

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 (123) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/docs/self-hosting/examples/ollama.mdx +1 -1
  3. package/docs/self-hosting/examples/ollama.zh-CN.mdx +1 -1
  4. package/locales/ar/plugin.json +1 -0
  5. package/locales/ar/portal.json +4 -0
  6. package/locales/bg-BG/plugin.json +1 -0
  7. package/locales/bg-BG/portal.json +4 -0
  8. package/locales/de-DE/plugin.json +1 -0
  9. package/locales/de-DE/portal.json +4 -0
  10. package/locales/en-US/plugin.json +1 -0
  11. package/locales/en-US/portal.json +4 -0
  12. package/locales/es-ES/plugin.json +1 -0
  13. package/locales/es-ES/portal.json +4 -0
  14. package/locales/fr-FR/plugin.json +1 -0
  15. package/locales/fr-FR/portal.json +4 -0
  16. package/locales/it-IT/plugin.json +1 -0
  17. package/locales/it-IT/portal.json +4 -0
  18. package/locales/ja-JP/plugin.json +1 -0
  19. package/locales/ja-JP/portal.json +4 -0
  20. package/locales/ko-KR/plugin.json +1 -0
  21. package/locales/ko-KR/portal.json +4 -0
  22. package/locales/nl-NL/plugin.json +1 -0
  23. package/locales/nl-NL/portal.json +4 -0
  24. package/locales/pl-PL/plugin.json +1 -0
  25. package/locales/pl-PL/portal.json +4 -0
  26. package/locales/pt-BR/plugin.json +1 -0
  27. package/locales/pt-BR/portal.json +4 -0
  28. package/locales/ru-RU/plugin.json +1 -0
  29. package/locales/ru-RU/portal.json +4 -0
  30. package/locales/tr-TR/plugin.json +1 -0
  31. package/locales/tr-TR/portal.json +4 -0
  32. package/locales/vi-VN/plugin.json +1 -0
  33. package/locales/vi-VN/portal.json +4 -0
  34. package/locales/zh-CN/plugin.json +1 -0
  35. package/locales/zh-CN/portal.json +4 -0
  36. package/locales/zh-TW/plugin.json +1 -0
  37. package/locales/zh-TW/portal.json +4 -0
  38. package/package.json +1 -1
  39. package/src/app/(main)/chat/(workspace)/@portal/_layout/Desktop.tsx +17 -0
  40. package/src/app/(main)/chat/(workspace)/@portal/_layout/Mobile.tsx +18 -0
  41. package/src/app/(main)/chat/(workspace)/@portal/default.tsx +27 -0
  42. package/src/app/(main)/chat/(workspace)/@portal/features/Header.tsx +52 -0
  43. package/src/app/(main)/chat/(workspace)/@portal/features/Tools/ToolList/Item/index.tsx +74 -0
  44. package/src/app/(main)/chat/(workspace)/@portal/features/Tools/ToolList/Item/style.ts +46 -0
  45. package/src/app/(main)/chat/(workspace)/@portal/features/Tools/ToolList/index.tsx +39 -0
  46. package/src/app/(main)/chat/(workspace)/@portal/features/Tools/ToolUI/Footer.tsx +33 -0
  47. package/src/app/(main)/chat/(workspace)/@portal/features/Tools/ToolUI/ToolRender.tsx +50 -0
  48. package/src/app/(main)/chat/(workspace)/@portal/features/Tools/ToolUI/index.tsx +37 -0
  49. package/src/app/(main)/chat/(workspace)/@portal/index.tsx +18 -0
  50. package/src/app/(main)/chat/(workspace)/_layout/Desktop/Portal.tsx +79 -0
  51. package/src/app/(main)/chat/(workspace)/_layout/Desktop/TopicPanel.tsx +27 -22
  52. package/src/app/(main)/chat/(workspace)/_layout/Desktop/index.tsx +3 -1
  53. package/src/app/(main)/chat/(workspace)/_layout/type.ts +1 -0
  54. package/src/app/(main)/chat/loading.tsx +2 -20
  55. package/src/components/CircleLoading/index.tsx +21 -0
  56. package/src/const/layoutTokens.test.ts +11 -0
  57. package/src/const/layoutTokens.ts +4 -0
  58. package/src/const/message.ts +0 -14
  59. package/src/database/client/models/__tests__/message.test.ts +9 -12
  60. package/src/database/client/models/message.ts +6 -0
  61. package/src/database/server/models/__tests__/message.test.ts +70 -0
  62. package/src/database/server/models/message.ts +10 -0
  63. package/src/database/server/schemas/lobechat.ts +3 -1
  64. package/src/features/Conversation/Messages/Assistant/ToolCalls/index.tsx +3 -17
  65. package/src/features/Conversation/Messages/Tool/Inspector/index.tsx +26 -2
  66. package/src/features/Conversation/Messages/Tool/index.tsx +33 -6
  67. package/src/features/Conversation/Messages/components/Arguments.tsx +1 -1
  68. package/src/features/PluginAvatar/index.tsx +28 -0
  69. package/src/features/PluginsUI/Render/BuiltinType/index.tsx +44 -0
  70. package/src/features/{Conversation/Plugins → PluginsUI}/Render/StandaloneType/index.tsx +8 -1
  71. package/src/features/{Conversation/Plugins → PluginsUI}/Render/index.tsx +12 -1
  72. package/src/{features/Conversation/Messages/hooks → hooks}/useYamlArguments.ts +3 -1
  73. package/src/locales/default/index.ts +2 -0
  74. package/src/locales/default/plugin.ts +1 -0
  75. package/src/locales/default/portal.ts +4 -0
  76. package/src/middleware.ts +6 -1
  77. package/src/server/routers/lambda/message.ts +12 -0
  78. package/src/services/message/client.test.ts +35 -0
  79. package/src/services/message/client.ts +6 -0
  80. package/src/services/message/server.ts +9 -0
  81. package/src/store/chat/initialState.ts +10 -1
  82. package/src/store/chat/selectors.ts +1 -0
  83. package/src/store/chat/slices/message/action.test.ts +1 -1
  84. package/src/store/chat/slices/message/action.ts +5 -5
  85. package/src/store/chat/slices/message/reducer.test.ts +230 -7
  86. package/src/store/chat/slices/message/reducer.ts +45 -22
  87. package/src/store/chat/slices/message/selectors.test.ts +133 -2
  88. package/src/store/chat/slices/message/selectors.ts +7 -0
  89. package/src/store/chat/slices/plugin/action.test.ts +309 -2
  90. package/src/store/chat/slices/plugin/action.ts +51 -1
  91. package/src/store/chat/slices/portal/action.test.ts +109 -0
  92. package/src/store/chat/slices/portal/action.ts +31 -0
  93. package/src/store/chat/slices/portal/initialState.ts +8 -0
  94. package/src/store/chat/slices/portal/selectors.test.ts +73 -0
  95. package/src/store/chat/slices/portal/selectors.ts +15 -0
  96. package/src/store/chat/store.ts +7 -1
  97. package/src/store/tool/selectors/tool.test.ts +14 -0
  98. package/src/store/tool/selectors/tool.ts +13 -0
  99. package/src/tools/docks.ts +3 -0
  100. package/src/types/tool/builtin.ts +11 -1
  101. package/src/utils/safeParseJSON.test.ts +71 -0
  102. package/src/utils/safeParseJSON.ts +12 -0
  103. package/src/const/message.test.ts +0 -55
  104. package/src/features/Conversation/Plugins/Render/BuiltinType/index.tsx +0 -30
  105. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/BuiltinType/index.test.tsx +0 -0
  106. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/DefaultType/IFrameRender/index.tsx +0 -0
  107. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/DefaultType/SystemJsRender/index.tsx +0 -0
  108. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/DefaultType/SystemJsRender/utils.ts +0 -0
  109. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/DefaultType/index.tsx +0 -0
  110. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/Loading.tsx +0 -0
  111. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/MarkdownType/index.tsx +0 -0
  112. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/StandaloneType/Iframe.tsx +0 -0
  113. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/useParseContent.ts +0 -0
  114. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/utils/iframeOnReady.test.ts +0 -0
  115. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/utils/iframeOnReady.ts +0 -0
  116. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/utils/listenToPlugin.test.ts +0 -0
  117. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/utils/listenToPlugin.ts +0 -0
  118. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/utils/pluginSettings.test.ts +0 -0
  119. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/utils/pluginSettings.ts +0 -0
  120. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/utils/pluginState.test.ts +0 -0
  121. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/utils/pluginState.ts +0 -0
  122. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/utils/postMessage.test.ts +0 -0
  123. /package/src/features/{Conversation/Plugins → PluginsUI}/Render/utils/postMessage.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.1.17](https://github.com/lobehub/lobe-chat/compare/v1.1.16...v1.1.17)
6
+
7
+ <sup>Released on **2024-07-01**</sup>
8
+
9
+ #### ♻ Code Refactoring
10
+
11
+ - **misc**: Refactor to prepare for Chat Portal.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### Code refactoring
19
+
20
+ - **misc**: Refactor to prepare for Chat Portal, closes [#3093](https://github.com/lobehub/lobe-chat/issues/3093) ([e7c1ba8](https://github.com/lobehub/lobe-chat/commit/e7c1ba8))
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.1.16](https://github.com/lobehub/lobe-chat/compare/v1.1.15...v1.1.16)
31
+
32
+ <sup>Released on **2024-06-29**</sup>
33
+
34
+ #### 🐛 Bug Fixes
35
+
36
+ - **misc**: Fix clerk `UNAUTHORIZED` error after long-time hang-up.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### What's fixed
44
+
45
+ - **misc**: Fix clerk `UNAUTHORIZED` error after long-time hang-up, closes [#3084](https://github.com/lobehub/lobe-chat/issues/3084) ([a148c3b](https://github.com/lobehub/lobe-chat/commit/a148c3b))
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.1.15](https://github.com/lobehub/lobe-chat/compare/v1.1.14...v1.1.15)
6
56
 
7
57
  <sup>Released on **2024-06-28**</sup>
@@ -27,7 +27,7 @@ First, you need to install Ollama. For detailed steps on installing and configur
27
27
  Assuming you have already started the Ollama service locally on port `11434`. Run the following Docker command to start LobeChat locally:
28
28
 
29
29
  ```bash
30
- docker run -d -p 3210:3210 -e OLLAMA_PROXY_URL=http://host.docker.internal:11434/v1 lobehub/lobe-chat
30
+ docker run -d -p 3210:3210 -e OLLAMA_PROXY_URL=http://host.docker.internal:11434 lobehub/lobe-chat
31
31
  ```
32
32
 
33
33
  Now, you can use LobeChat to converse with the local LLM.
@@ -25,7 +25,7 @@ Ollama 是一款强大的本地运行大型语言模型(LLM)的框架,支
25
25
  假设你已经在本地 `11434` 端口启动了 Ollama 服务。运行以下 Docker 命令行,在本地启动 LobeChat:
26
26
 
27
27
  ```bash
28
- docker run -d -p 3210:3210 -e OLLAMA_PROXY_URL=http://host.docker.internal:11434/v1 lobehub/lobe-chat
28
+ docker run -d -p 3210:3210 -e OLLAMA_PROXY_URL=http://host.docker.internal:11434 lobehub/lobe-chat
29
29
  ```
30
30
 
31
31
  接下来,你就可以使用 LobeChat 与本地 LLM 对话了。
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "بعد ضبط عنوان سوق الإضافات، يمكن استخدام سوق الإضافات المخصص",
140
140
  "title": "ضبط سوق الإضافات"
141
141
  },
142
+ "showInPortal": "يرجى الاطلاع على التفاصيل في النافذة المنبثقة",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "سيتم إلغاء تثبيت الإضافة، وسيتم مسح تكوين الإضافة، يرجى تأكيد العملية",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "تلخيص من قبل المساعد",
3
+ "title": "نافذة موسعة"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "След като конфигурирате адреса на пазара на плъгини, можете да използвате персонализиран пазар на плъгини",
140
140
  "title": "Конфигуриране на пазара на плъгини"
141
141
  },
142
+ "showInPortal": "Моля, вижте подробностите в разширеното прозорец",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "Плъгинът е на път да бъде деинсталиран. След деинсталирането конфигурацията на плъгина ще бъде изчистена. Моля, потвърдете операцията си.",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "Сумиране от помощник",
3
+ "title": "Разширено прозорец"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "Nachdem Sie die Adresse des Plugin-Marktes konfiguriert haben, können Sie den benutzerdefinierten Plugin-Markt verwenden.",
140
140
  "title": "Plugin-Markteinstellungen"
141
141
  },
142
+ "showInPortal": "Bitte überprüfen Sie die Details im Erweiterungsfenster",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "Das Plugin wird deinstalliert und alle Konfigurationen werden gelöscht. Bitte bestätigen Sie Ihre Aktion.",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "Lassen Sie den Assistenten zusammenfassen",
3
+ "title": "Erweiterungsfenster"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "After configuring the address of the plugin marketplace, you can use a custom plugin marketplace",
140
140
  "title": "Configure Plugin Marketplace"
141
141
  },
142
+ "showInPortal": "Please view details in the extension window",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "The plugin is about to be uninstalled. After uninstalling, the plugin configuration will be cleared. Please confirm your operation.",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "Let the assistant summarize",
3
+ "title": "Expand Window"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "Después de configurar la dirección del mercado de complementos, puede utilizar un mercado personalizado de complementos.",
140
140
  "title": "Configuración del mercado de complementos"
141
141
  },
142
+ "showInPortal": "Por favor, consulta los detalles en la ventana de expansión",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "Está a punto de desinstalar este complemento. Se eliminará la configuración del complemento. Confirme su acción.",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "Resumen del asistente",
3
+ "title": "Ventana de expansión"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "Une fois l'adresse du marché des plugins configurée, vous pourrez utiliser un marché de plugins personnalisé.",
140
140
  "title": "Paramètres du marché des plugins"
141
141
  },
142
+ "showInPortal": "Veuillez consulter les détails dans la fenêtre d'extension",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "Vous êtes sur le point de désinstaller ce plugin. Une fois désinstallé, sa configuration sera effacée. Veuillez confirmer votre action.",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "Faire un résumé avec l'assistant",
3
+ "title": "Fenêtre d'extension"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "Dopo aver configurato l'indirizzo del mercato dei plugin, è possibile utilizzare un mercato dei plugin personalizzato",
140
140
  "title": "Impostazioni del mercato dei plugin"
141
141
  },
142
+ "showInPortal": "Si prega di visualizzare i dettagli nella finestra di estensione",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "Stai per disinstallare questo plugin. La disinstallazione cancellerà la configurazione del plugin. Conferma l'operazione",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "Riepilogo assistente",
3
+ "title": "Finestra di espansione"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "プラグインマーケットのアドレスを設定すると、カスタムのプラグインマーケットを使用できます",
140
140
  "title": "プラグインマーケットの設定"
141
141
  },
142
+ "showInPortal": "詳細は拡張ウィンドウで表示してください",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "このプラグインをアンインストールします。アンインストール後、プラグインの設定がクリアされます。操作を確認してください。",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "アシスタントに要約させる",
3
+ "title": "拡張ウィンドウ"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "플러그인 마켓의 주소를 구성하면 사용자 정의 플러그인 마켓을 사용할 수 있습니다.",
140
140
  "title": "플러그인 마켓 설정"
141
141
  },
142
+ "showInPortal": "확장 창에서 자세히 보기",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "이 플러그인을 제거하려고 합니다. 제거하면 플러그인 구성이 지워지므로 작업을 확인하세요.",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "어시스턴트 요약",
3
+ "title": "확장 창"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "Na het instellen van de marktlocatie voor plugins, kunt u een aangepaste pluginmarkt gebruiken.",
140
140
  "title": "Instellingen voor pluginmarkt"
141
141
  },
142
+ "showInPortal": "Gelieve de details te bekijken in het uitbreidingsvenster",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "Deze plugin wordt binnenkort verwijderd. Na verwijdering worden de configuraties gewist. Weet u zeker dat u door wilt gaan?",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "Laat de assistent samenvatten",
3
+ "title": "Uitbreidingsvenster"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "Po skonfigurowaniu adresu sklepu wtyczek możesz korzystać z niestandardowego sklepu wtyczek",
140
140
  "title": "Skonfiguruj sklep wtyczek"
141
141
  },
142
+ "showInPortal": "Proszę sprawdzić szczegóły w oknie rozszerzenia",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "Wtyczka zostanie odinstalowana. Po odinstalowaniu konfiguracja wtyczki zostanie wyczyszczona. Potwierdź swoje działanie.",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "Podsumowanie przez asystenta",
3
+ "title": "Okno rozszerzenia"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "Após configurar o endereço do mercado de plugins, você poderá usar um mercado personalizado de plugins.",
140
140
  "title": "Configurações do Mercado de Plugins"
141
141
  },
142
+ "showInPortal": "Por favor, veja os detalhes na janela de extensão",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "Você está prestes a desinstalar este plugin. A desinstalação irá limpar a configuração do plugin. Confirme a operação.",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "Permita que o assistente resuma",
3
+ "title": "Janela de Expansão"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "После настройки адреса магазина плагинов можно использовать пользовательский магазин",
140
140
  "title": "Настройки магазина плагинов"
141
141
  },
142
+ "showInPortal": "Просмотрите подробности во всплывающем окне",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "Вы собираетесь удалить этот плагин. После удаления его настройки будут утрачены. Вы уверены, что хотите продолжить?",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "Попросите помощника сделать сводку",
3
+ "title": "Расширенное окно"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "Eklenti pazarı adresini yapılandırdıktan sonra, özel bir eklenti pazarı kullanabilirsiniz.",
140
140
  "title": "Eklenti Pazarı Ayarla"
141
141
  },
142
+ "showInPortal": "Detayları genişletme penceresinde görüntüleyin",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "Bu eklentiyi kaldırmak üzeresiniz, kaldırdıktan sonra eklenti yapılandırması temizlenecektir, işleminizi onaylayın",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "Asistanın özetlemesine izin ver",
3
+ "title": "Genişletme Penceresi"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "Sau khi cấu hình địa chỉ thị trường plugin, bạn có thể sử dụng thị trường plugin tùy chỉnh",
140
140
  "title": "Cài đặt thị trường plugin"
141
141
  },
142
+ "showInPortal": "Vui lòng xem chi tiết trong cửa sổ mở rộng",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "Sắp gỡ bỏ plugin này, sau khi gỡ bỏ sẽ xóa cấu hình của plugin này, vui lòng xác nhận hành động của bạn",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "Tóm tắt bởi trợ lý",
3
+ "title": "Cửa sổ mở rộng"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "配置插件市场的地址后,可以使用自定义的插件市场",
140
140
  "title": "设置插件市场"
141
141
  },
142
+ "showInPortal": "请在扩展窗中查看详情",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "即将卸载该插件,卸载后将清除该插件配置,请确认你的操作",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "让助手总结",
3
+ "title": "扩展窗"
4
+ }
@@ -139,6 +139,7 @@
139
139
  "modalDesc": "設定外掛市集的網址後,您可以使用自訂的外掛市集",
140
140
  "title": "設定外掛市集"
141
141
  },
142
+ "showInPortal": "請在入口網站中查看",
142
143
  "store": {
143
144
  "actions": {
144
145
  "confirmUninstall": "即將卸載該插件,卸載後將清除該插件配置,請確認你的操作",
@@ -0,0 +1,4 @@
1
+ {
2
+ "aiSummary": "讓助手總結",
3
+ "title": "擴展視窗"
4
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.1.15",
3
+ "version": "1.1.17",
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",
@@ -0,0 +1,17 @@
1
+ import { PropsWithChildren } from 'react';
2
+ import { Flexbox } from 'react-layout-kit';
3
+
4
+ import Header from '../features/Header';
5
+
6
+ const Layout = ({ children }: PropsWithChildren) => {
7
+ return (
8
+ <>
9
+ <Header />
10
+ <Flexbox height={'100%'} style={{ overflow: 'hidden', position: 'relative' }} width={'100%'}>
11
+ {children}
12
+ </Flexbox>
13
+ </>
14
+ );
15
+ };
16
+
17
+ export default Layout;
@@ -0,0 +1,18 @@
1
+ import { PropsWithChildren } from 'react';
2
+ import { Flexbox } from 'react-layout-kit';
3
+
4
+ const Layout = ({ children }: PropsWithChildren) => {
5
+ return (
6
+ <Flexbox gap={8} height={'100%'} padding={'8px 8px 0'} style={{ overflow: 'hidden' }}>
7
+ <Flexbox
8
+ height={'100%'}
9
+ style={{ marginInline: -8, overflow: 'hidden', position: 'relative' }}
10
+ width={'calc(100% + 16px)'}
11
+ >
12
+ {children}
13
+ </Flexbox>
14
+ </Flexbox>
15
+ );
16
+ };
17
+
18
+ export default Layout;
@@ -0,0 +1,27 @@
1
+ import React, { Suspense, lazy } from 'react';
2
+
3
+ import Loading from '@/components/CircleLoading';
4
+ import { isMobileDevice } from '@/utils/responsive';
5
+
6
+ import Desktop from './_layout/Desktop';
7
+ import Mobile from './_layout/Mobile';
8
+
9
+ const InspectorContent = lazy(() => import('./index'));
10
+
11
+ const Inspector = () => {
12
+ const mobile = isMobileDevice();
13
+
14
+ const Layout = mobile ? Mobile : Desktop;
15
+
16
+ return (
17
+ <Layout>
18
+ <Suspense fallback={<Loading />}>
19
+ <InspectorContent />
20
+ </Suspense>
21
+ </Layout>
22
+ );
23
+ };
24
+
25
+ Inspector.displayName = 'ChatInspector';
26
+
27
+ export default Inspector;
@@ -0,0 +1,52 @@
1
+ 'use client';
2
+
3
+ import { ActionIcon } from '@lobehub/ui';
4
+ import { Typography } from 'antd';
5
+ import isEqual from 'fast-deep-equal';
6
+ import { ArrowLeft, XIcon } from 'lucide-react';
7
+ import { memo } from 'react';
8
+ import { useTranslation } from 'react-i18next';
9
+ import { Flexbox } from 'react-layout-kit';
10
+
11
+ import SidebarHeader from '@/components/SidebarHeader';
12
+ import PluginAvatar from '@/features/PluginAvatar';
13
+ import { useChatStore } from '@/store/chat';
14
+ import { chatPortalSelectors } from '@/store/chat/selectors';
15
+ import { pluginHelpers, useToolStore } from '@/store/tool';
16
+ import { toolSelectors } from '@/store/tool/selectors';
17
+
18
+ const Header = memo(() => {
19
+ const [showToolUI, toggleInspector, closeToolUI, toolUIIdentifier = ''] = useChatStore((s) => [
20
+ chatPortalSelectors.showToolUI(s),
21
+ s.toggleDock,
22
+ s.closeToolUI,
23
+ chatPortalSelectors.toolUIIdentifier(s),
24
+ ]);
25
+
26
+ const { t } = useTranslation(['plugin', 'portal']);
27
+ const pluginMeta = useToolStore(toolSelectors.getMetaById(toolUIIdentifier), isEqual);
28
+ const pluginTitle = pluginHelpers.getPluginTitle(pluginMeta) ?? t('unknownPlugin');
29
+
30
+ return (
31
+ <SidebarHeader
32
+ actions={<ActionIcon icon={XIcon} onClick={() => toggleInspector(false)} />}
33
+ title={
34
+ showToolUI ? (
35
+ <Flexbox align={'center'} gap={4} horizontal>
36
+ <ActionIcon icon={ArrowLeft} onClick={() => closeToolUI()} />
37
+ <PluginAvatar identifier={toolUIIdentifier} size={28} />
38
+ <Typography.Text style={{ fontSize: 16 }} type={'secondary'}>
39
+ {pluginTitle}
40
+ </Typography.Text>
41
+ </Flexbox>
42
+ ) : (
43
+ <Typography.Text style={{ fontSize: 16 }} type={'secondary'}>
44
+ {t('portal:title')}
45
+ </Typography.Text>
46
+ )
47
+ }
48
+ />
49
+ );
50
+ });
51
+
52
+ export default Header;
@@ -0,0 +1,74 @@
1
+ import { Icon, Tag } from '@lobehub/ui';
2
+ import { Typography } from 'antd';
3
+ import isEqual from 'fast-deep-equal';
4
+ import { CircuitBoard } from 'lucide-react';
5
+ import { memo } from 'react';
6
+ import { useTranslation } from 'react-i18next';
7
+ import { Flexbox } from 'react-layout-kit';
8
+
9
+ import PluginAvatar from '@/features/PluginAvatar';
10
+ import { useYamlArguments } from '@/hooks/useYamlArguments';
11
+ import { useChatStore } from '@/store/chat';
12
+ import { pluginHelpers, useToolStore } from '@/store/tool';
13
+ import { toolSelectors } from '@/store/tool/selectors';
14
+ import { ChatPluginPayload } from '@/types/message';
15
+
16
+ import { useStyles } from './style';
17
+
18
+ export interface InspectorProps {
19
+ identifier?: string;
20
+ messageId: string;
21
+ payload?: ChatPluginPayload;
22
+ }
23
+
24
+ const Inspector = memo<InspectorProps>(({ payload, messageId, identifier = 'unknown' }) => {
25
+ const { t } = useTranslation('plugin');
26
+ const { styles, cx } = useStyles();
27
+
28
+ const args = useYamlArguments(payload?.arguments);
29
+
30
+ const pluginMeta = useToolStore(toolSelectors.getMetaById(identifier), isEqual);
31
+ const isToolHasUI = useToolStore(toolSelectors.isToolHasUI(identifier));
32
+ const openToolUI = useChatStore((s) => s.openToolUI);
33
+ const pluginTitle = pluginHelpers.getPluginTitle(pluginMeta) ?? t('unknownPlugin');
34
+
35
+ return (
36
+ <Flexbox
37
+ align={'center'}
38
+ className={styles.container}
39
+ gap={8}
40
+ horizontal
41
+ onClick={() => {
42
+ if (!isToolHasUI || !identifier) return;
43
+
44
+ openToolUI(messageId, identifier);
45
+ }}
46
+ >
47
+ <Flexbox align={'center'} distribution={'space-between'} gap={24} horizontal>
48
+ <Flexbox align={'center'} gap={8} horizontal>
49
+ <PluginAvatar identifier={identifier} />
50
+ <Flexbox gap={4}>
51
+ <Flexbox align={'center'} gap={8} horizontal>
52
+ <div>{pluginTitle}</div>
53
+ <Tag>{payload?.apiName}</Tag>
54
+ </Flexbox>
55
+ <div>
56
+ <Typography.Text ellipsis style={{ fontSize: 12 }} type={'secondary'}>
57
+ {args}
58
+ </Typography.Text>
59
+ </div>
60
+ </Flexbox>
61
+ </Flexbox>
62
+ <Flexbox>
63
+ {isToolHasUI && (
64
+ <div className={cx(styles.tag, styles.tagBlue)} style={{ cursor: 'pointer' }} title="">
65
+ <Icon icon={CircuitBoard} />
66
+ </div>
67
+ )}
68
+ </Flexbox>
69
+ </Flexbox>
70
+ </Flexbox>
71
+ );
72
+ });
73
+
74
+ export default Inspector;
@@ -0,0 +1,46 @@
1
+ import { createStyles } from 'antd-style';
2
+
3
+ export const useStyles = createStyles(({ css, token }) => ({
4
+ container: css`
5
+ cursor: pointer;
6
+
7
+ width: 100%;
8
+ padding: 10px 8px;
9
+ padding-inline-end: 12px;
10
+
11
+ color: ${token.colorText};
12
+
13
+ background: ${token.colorBgContainer};
14
+ border-radius: 8px;
15
+
16
+ &:hover {
17
+ background: ${token.colorFillSecondary};
18
+ }
19
+ `,
20
+ plugin: css`
21
+ display: flex;
22
+ gap: 4px;
23
+ align-items: center;
24
+ width: fit-content;
25
+ `,
26
+ tag: css`
27
+ cursor: default;
28
+
29
+ display: flex;
30
+ align-items: center;
31
+ justify-content: center;
32
+
33
+ width: 24px;
34
+ height: 24px;
35
+
36
+ border-radius: 4px;
37
+ `,
38
+ tagBlue: css`
39
+ color: ${token.geekblue};
40
+ background: ${token.geekblue1};
41
+ `,
42
+ tagGreen: css`
43
+ color: ${token.green};
44
+ background: ${token.green1};
45
+ `,
46
+ }));
@@ -0,0 +1,39 @@
1
+ import { Skeleton } from 'antd';
2
+ import isEqual from 'fast-deep-equal';
3
+ import { Flexbox } from 'react-layout-kit';
4
+
5
+ import { useChatStore } from '@/store/chat';
6
+ import { chatSelectors } from '@/store/chat/selectors';
7
+
8
+ import ToolItem from './Item';
9
+
10
+ const ToolList = () => {
11
+ const messages = useChatStore(chatSelectors.currentToolMessages, isEqual);
12
+ const isCurrentChatLoaded = useChatStore(chatSelectors.isCurrentChatLoaded);
13
+
14
+ return !isCurrentChatLoaded ? (
15
+ <Flexbox gap={12} paddingInline={12}>
16
+ {[1, 1, 1, 1, 1, 1].map((key, index) => (
17
+ <Skeleton.Button
18
+ active
19
+ block
20
+ key={`${key}-${index}`}
21
+ style={{ borderRadius: 8, height: 68 }}
22
+ />
23
+ ))}
24
+ </Flexbox>
25
+ ) : (
26
+ <Flexbox gap={12} paddingInline={12}>
27
+ {messages.map((m) => (
28
+ <ToolItem
29
+ identifier={m.plugin?.identifier}
30
+ key={m.id}
31
+ messageId={m.id}
32
+ payload={m.plugin}
33
+ />
34
+ ))}
35
+ </Flexbox>
36
+ );
37
+ };
38
+
39
+ export default ToolList;