@lobehub/chat 0.111.5 → 0.112.0

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 (148) hide show
  1. package/.env.example +1 -1
  2. package/.i18nrc.js +1 -0
  3. package/CHANGELOG.md +84 -0
  4. package/README.md +2 -2
  5. package/README.zh-CN.md +2 -2
  6. package/docs/Deployment/Environment-Variable.md +1 -1
  7. package/docs/Deployment/Environment-Variable.zh-CN.md +1 -1
  8. package/docs/Deployment/Upstream-Sync.md +1 -1
  9. package/docs/Deployment/Upstream-Sync.zh-CN.md +1 -1
  10. package/docs/Home.md +26 -26
  11. package/docs/Plugins/Plugin-Development.md +1 -1
  12. package/docs/Plugins/Plugin-Development.zh-CN.md +1 -1
  13. package/docs/_Sidebar.md +20 -20
  14. package/locales/en_US/chat.json +12 -12
  15. package/locales/en_US/common.json +13 -13
  16. package/locales/en_US/error.json +16 -14
  17. package/locales/en_US/market.json +2 -2
  18. package/locales/en_US/migration.json +4 -4
  19. package/locales/en_US/plugin.json +75 -38
  20. package/locales/en_US/setting.json +7 -7
  21. package/locales/fr_FR/chat.json +11 -11
  22. package/locales/fr_FR/common.json +14 -14
  23. package/locales/fr_FR/error.json +12 -10
  24. package/locales/fr_FR/plugin.json +42 -5
  25. package/locales/fr_FR/setting.json +12 -12
  26. package/locales/fr_FR/welcome.json +3 -3
  27. package/locales/ja_JP/chat.json +1 -1
  28. package/locales/ja_JP/common.json +3 -3
  29. package/locales/ja_JP/error.json +16 -14
  30. package/locales/ja_JP/migration.json +4 -4
  31. package/locales/ja_JP/plugin.json +70 -33
  32. package/locales/ja_JP/setting.json +1 -1
  33. package/locales/ko_KR/chat.json +1 -1
  34. package/locales/ko_KR/common.json +3 -3
  35. package/locales/ko_KR/error.json +16 -14
  36. package/locales/ko_KR/migration.json +4 -4
  37. package/locales/ko_KR/plugin.json +71 -34
  38. package/locales/ko_KR/setting.json +1 -1
  39. package/locales/ru_RU/chat.json +1 -1
  40. package/locales/ru_RU/common.json +3 -3
  41. package/locales/ru_RU/error.json +16 -14
  42. package/locales/ru_RU/market.json +2 -2
  43. package/locales/ru_RU/migration.json +4 -4
  44. package/locales/ru_RU/plugin.json +71 -34
  45. package/locales/ru_RU/setting.json +1 -1
  46. package/locales/zh_CN/chat.json +1 -1
  47. package/locales/zh_CN/common.json +1 -1
  48. package/locales/zh_CN/error.json +2 -0
  49. package/locales/zh_CN/plugin.json +42 -5
  50. package/locales/zh_CN/setting.json +1 -1
  51. package/locales/zh_TW/chat.json +1 -1
  52. package/locales/zh_TW/common.json +3 -3
  53. package/locales/zh_TW/error.json +16 -14
  54. package/locales/zh_TW/market.json +2 -2
  55. package/locales/zh_TW/migration.json +4 -4
  56. package/locales/zh_TW/plugin.json +98 -61
  57. package/locales/zh_TW/setting.json +1 -1
  58. package/package.json +3 -1
  59. package/scripts/docsWorkflow/index.ts +5 -2
  60. package/scripts/docsWorkflow/toc.ts +2 -2
  61. package/scripts/i18nWorkflow/genDiff.ts +7 -8
  62. package/scripts/i18nWorkflow/utils.ts +0 -14
  63. package/scripts/readmeWorkflow/syncPluginIndex.ts +9 -11
  64. package/src/app/api/plugins/route.ts +2 -4
  65. package/src/app/api/proxy/route.ts +10 -0
  66. package/src/app/chat/features/ChatInput/ActionBar/Tools/ToolItem.tsx +3 -8
  67. package/src/app/chat/features/ChatInput/ActionBar/Tools/index.tsx +3 -3
  68. package/src/app/chat/features/Conversation/ChatList/Error/index.tsx +6 -0
  69. package/src/app/chat/features/Conversation/ChatList/Messages/Function.tsx +1 -1
  70. package/src/app/chat/features/Conversation/ChatList/Plugins/Inspector/Settings.tsx +7 -5
  71. package/src/app/chat/features/Conversation/ChatList/Plugins/Inspector/index.tsx +2 -2
  72. package/src/app/chat/features/Conversation/ChatList/Plugins/Render/DefaultType/index.tsx +6 -4
  73. package/src/app/chat/features/Conversation/ChatList/Plugins/Render/index.tsx +2 -2
  74. package/src/app/chat/features/Migration/ExportConfigButton.tsx +1 -1
  75. package/src/app/market/features/AgentDetailContent/AgentInfo/index.tsx +1 -0
  76. package/src/app/market/features/AgentDetailContent/AgentInfo/style.ts +1 -9
  77. package/src/app/settings/common/Common.tsx +5 -7
  78. package/src/app/settings/features/UpgradeAlert.tsx +2 -2
  79. package/src/components/FileList/FileItem.tsx +4 -2
  80. package/src/components/HotKeys/index.tsx +5 -4
  81. package/src/const/plugin.ts +1 -0
  82. package/src/const/url.ts +1 -0
  83. package/src/const/version.ts +0 -3
  84. package/src/features/AgentSetting/AgentPlugin/AddPluginButton.tsx +2 -2
  85. package/src/features/AgentSetting/AgentPlugin/LocalPluginItem.tsx +19 -53
  86. package/src/features/AgentSetting/AgentPlugin/index.tsx +5 -11
  87. package/src/features/AgentSetting/store/initialState.ts +1 -1
  88. package/src/features/PluginDetailModal/APIs.tsx +44 -0
  89. package/src/features/PluginDetailModal/Meta.tsx +59 -0
  90. package/src/features/PluginDetailModal/index.tsx +79 -0
  91. package/src/features/PluginDevModal/PluginPreview.tsx +8 -10
  92. package/src/features/PluginDevModal/UrlManifestForm.tsx +131 -0
  93. package/src/features/PluginDevModal/index.tsx +31 -32
  94. package/src/features/PluginSettings/index.tsx +1 -1
  95. package/src/features/PluginStore/AddPluginButton.tsx +47 -0
  96. package/src/features/PluginStore/InstalledPluginList.tsx +54 -0
  97. package/src/features/PluginStore/OnlineList.tsx +95 -0
  98. package/src/features/PluginStore/PluginItem/Action.tsx +118 -0
  99. package/src/features/PluginStore/PluginItem/EditCustomPlugin.tsx +50 -0
  100. package/src/features/PluginStore/PluginItem/PluginTag.tsx +58 -0
  101. package/src/features/PluginStore/PluginItem/index.tsx +73 -0
  102. package/src/features/PluginStore/index.tsx +20 -92
  103. package/src/hooks/usePlatform.ts +15 -0
  104. package/src/locales/default/chat.ts +1 -1
  105. package/src/locales/default/common.ts +1 -1
  106. package/src/locales/default/error.ts +2 -0
  107. package/src/locales/default/plugin.ts +41 -4
  108. package/src/locales/default/setting.ts +1 -1
  109. package/src/services/__tests__/__snapshots__/plugin.test.ts.snap +154 -0
  110. package/src/services/__tests__/chat.test.ts +1 -1
  111. package/src/services/__tests__/global.test.ts +57 -0
  112. package/src/services/__tests__/openai/OpenAPI_V3.json +245 -0
  113. package/src/services/__tests__/openai/plugin.json +22 -0
  114. package/src/services/__tests__/plugin.test.ts +90 -1
  115. package/src/services/__tests__/share.test.ts +86 -0
  116. package/src/services/_url.ts +2 -0
  117. package/src/services/global.ts +15 -0
  118. package/src/services/plugin.ts +99 -15
  119. package/src/services/share.ts +34 -0
  120. package/src/store/chat/actions/enhance.test.ts +15 -15
  121. package/src/store/chat/actions/message.test.ts +3 -2
  122. package/src/store/chat/actions/plugin.test.ts +281 -0
  123. package/src/store/chat/actions/plugin.ts +22 -3
  124. package/src/store/chat/actions/share.ts +2 -2
  125. package/src/store/chat/actions/topic.test.ts +12 -4
  126. package/src/store/global/slices/common.ts +2 -2
  127. package/src/store/session/selectors.ts +1 -1
  128. package/src/store/session/slices/agent/selectors.ts +1 -1
  129. package/src/store/tool/helpers.ts +8 -1
  130. package/src/store/tool/slices/customPlugin/action.ts +4 -1
  131. package/src/store/tool/slices/plugin/selectors.test.ts +22 -3
  132. package/src/store/tool/slices/plugin/selectors.ts +24 -5
  133. package/src/store/tool/slices/store/selectors.test.ts +18 -1
  134. package/src/store/tool/slices/store/selectors.ts +14 -3
  135. package/src/styles/antdOverride.ts +7 -0
  136. package/src/types/openai/chat.ts +0 -1
  137. package/src/types/openai/plugin.ts +57 -0
  138. package/src/types/tool/index.ts +1 -2
  139. package/src/types/tool/plugin.ts +13 -1
  140. package/src/types/tool/tool.ts +1 -0
  141. package/src/types/translate.ts +0 -1
  142. package/src/utils/platform.ts +8 -5
  143. package/src/features/PluginDevModal/UrlModeForm.tsx +0 -98
  144. package/src/features/PluginSettingsModal/index.tsx +0 -59
  145. package/src/features/PluginStore/PluginItem.tsx +0 -82
  146. package/src/features/PluginStore/PluginSettings.tsx +0 -40
  147. package/src/services/latestVersion.ts +0 -11
  148. package/src/services/shareGPT.ts +0 -28
@@ -1,129 +1,166 @@
1
1
  {
2
2
  "debug": {
3
- "arguments": "調用參數",
4
- "function_call": "函數調用",
5
- "off": "關閉調試",
6
- "on": "查看插件調用信息",
7
- "response": "返回結果"
3
+ "arguments": "參數",
4
+ "function_call": "函式呼叫",
5
+ "off": "關閉偵錯",
6
+ "on": "查看插件呼叫資訊",
7
+ "response": "回應"
8
+ },
9
+ "detailModal": {
10
+ "info": {
11
+ "description": "API 描述",
12
+ "name": "API 名稱"
13
+ },
14
+ "tabs": {
15
+ "info": "插件能力",
16
+ "manifest": "安裝檔案",
17
+ "settings": "設定"
18
+ },
19
+ "title": "插件詳情"
8
20
  },
9
21
  "dev": {
10
- "confirmDeleteDevPlugin": "即將刪除該本地插件,刪除後將無法找回,是否刪除該插件?",
11
- "deleteSuccess": "插件刪除成功",
22
+ "confirmDeleteDevPlugin": "您確定要刪除此本機外掛嗎?一旦刪除,將無法復原。",
23
+ "customParams": {
24
+ "useProxy": {
25
+ "label": "透過代理安裝(若遇到跨域訪問錯誤,可嘗試開啟該選項後重新安裝)"
26
+ }
27
+ },
28
+ "deleteSuccess": "外掛已成功刪除",
12
29
  "manifest": {
13
30
  "identifier": {
14
- "desc": "插件的唯一標識",
15
- "label": "標識符"
31
+ "desc": "外掛的唯一識別碼",
32
+ "label": "識別碼"
16
33
  },
17
34
  "mode": {
18
- "local": "可視化配置",
19
- "local-tooltip": "暫時不支持可視化配置",
20
- "url": "在線鏈接"
35
+ "local": "視覺設定",
36
+ "local-tooltip": "目前不支援視覺設定",
37
+ "url": "線上連結"
21
38
  },
22
39
  "name": {
23
- "desc": "插件標題",
24
- "label": "標題",
25
- "placeholder": "搜索引擎"
40
+ "desc": "外掛的名稱",
41
+ "label": "名稱",
42
+ "placeholder": "搜尋引擎"
26
43
  }
27
44
  },
28
45
  "meta": {
29
46
  "author": {
30
- "desc": "插件的作者",
47
+ "desc": "外掛的作者",
31
48
  "label": "作者"
32
49
  },
33
50
  "avatar": {
34
- "desc": "插件的圖標,可以使用 Emoji,也可以使用 URL",
35
- "label": "圖標"
51
+ "desc": "外掛的圖示,可以是 Emoji 或網址",
52
+ "label": "圖示"
36
53
  },
37
54
  "description": {
38
- "desc": "插件描述",
55
+ "desc": "外掛的描述",
39
56
  "label": "描述",
40
- "placeholder": "查詢搜索引擎獲取信息"
57
+ "placeholder": "從搜尋引擎取得資訊"
41
58
  },
42
- "formFieldRequired": "該字段為必填項",
59
+ "formFieldRequired": "此欄位必填",
43
60
  "homepage": {
44
- "desc": "插件的首頁",
61
+ "desc": "外掛的官方首頁",
45
62
  "label": "首頁"
46
63
  },
47
64
  "identifier": {
48
- "desc": "插件的唯一標識,將從 manifest 中自動識別",
49
- "errorDuplicate": "標識符和已有插件重複,請修改標識符",
50
- "label": "標識符",
51
- "pattenErrorMessage": "只能輸入英文字符、數字 、- 和_ 這兩個符號"
65
+ "desc": "外掛的唯一識別碼,只支援英數字元、連字號 -,以及底線 _",
66
+ "errorDuplicate": "此識別碼已被其他外掛使用,請更改識別碼",
67
+ "label": "識別碼",
68
+ "pattenErrorMessage": "只允許英數字元、連字號 -,以及底線 _"
52
69
  },
53
70
  "manifest": {
54
- "desc": "LobeChat 將會通過該鏈接安裝插件",
55
- "label": "插件描述文件 (Manifest) URL",
71
+ "desc": "LobeChat 會使用此連結安裝外掛",
72
+ "label": "插件描述檔 (Manifest) URL",
56
73
  "preview": "預覽 Manifest",
57
- "refresh": "刷新"
74
+ "refresh": "重新載入"
58
75
  },
59
76
  "title": {
60
- "desc": "插件標題",
61
- "label": "標題",
62
- "placeholder": "搜索引擎"
77
+ "desc": "外掛的名稱",
78
+ "label": "名稱",
79
+ "placeholder": "搜尋引擎"
63
80
  }
64
81
  },
65
- "metaConfig": "插件元信息配置",
66
- "modalDesc": "添加自定義插件後,可用於插件開發驗證,也可直接在會話中使用。插件開發請參考<1>開發文檔↗</>",
82
+ "metaConfig": "外掛後設資料設定",
83
+ "modalDesc": "添加自訂插件後,可用於插件開發驗證,也可直接在會話中使用。插件開發請參考<1>開發文件↗</>",
84
+ "openai": {
85
+ "importUrl": "從 URL 連結匯入",
86
+ "schema": "Schema"
87
+ },
67
88
  "preview": {
68
- "card": "預覽插件展示效果",
69
- "desc": "預覽插件描述",
70
- "title": "插件名稱預覽"
89
+ "card": "外掛顯示預覽",
90
+ "desc": "外掛描述預覽",
91
+ "title": "外掛名稱預覽"
71
92
  },
72
93
  "save": "安裝插件",
73
- "saveSuccess": "插件設置保存成功",
94
+ "saveSuccess": "外掛設定已成功儲存",
74
95
  "tabs": {
75
96
  "manifest": "功能描述清單 (Manifest)",
76
- "meta": "插件元信息"
97
+ "meta": "外掛後設資料"
98
+ },
99
+ "title": {
100
+ "create": "新增自訂插件",
101
+ "edit": "編輯自訂插件"
102
+ },
103
+ "type": {
104
+ "lobe": "LobeChat 插件",
105
+ "openai": "OpenAI 插件"
77
106
  },
78
- "title": "添加自定義插件",
79
107
  "update": "更新",
80
- "updateSuccess": "插件設置更新成功"
108
+ "updateSuccess": "外掛設定已成功更新"
81
109
  },
82
110
  "error": {
83
- "fetchError": "請求該 manifest 鏈接失敗,請確保鏈接的有效性,並檢查鏈接是否允許跨域訪問",
111
+ "fetchError": "請求該 manifest 連結失敗,請確保連結的有效性,並檢查連結是否允許跨域訪問",
84
112
  "installError": "插件 {{name}} 安裝失敗",
85
- "manifestInvalid": " manifest 不符合規範,校驗結果: \n\n {{error}}",
86
- "noManifest": "描述文件不存在",
113
+ "manifestInvalid": "manifest 不符合規範,校驗結果: \n\n {{error}}",
114
+ "noManifest": "描述檔不存在",
115
+ "openAPIInvalid": "OpenAPI 解析失敗,錯誤: \n\n {{error}}",
87
116
  "reinstallError": "插件 {{name}} 刷新失敗",
88
- "urlError": "該鏈接沒有返回 JSON 格式的內容, 請確保是有效的鏈接"
117
+ "urlError": "該連結沒有返回 JSON 格式的內容, 請確保是有效的連結"
89
118
  },
90
119
  "list": {
91
120
  "item": {
92
121
  "deprecated.title": "已刪除",
93
- "local.config": "配置",
94
- "local.title": "自定義"
122
+ "local.config": "設定",
123
+ "local.title": "本機"
95
124
  }
96
125
  },
97
126
  "loading": {
98
- "content": "調用插件中...",
99
- "plugin": "插件運行中..."
127
+ "content": "呼叫插件中...",
128
+ "plugin": "外掛執行中..."
100
129
  },
101
- "pluginList": "插件列表",
130
+ "pluginList": "外掛清單",
102
131
  "plugins": {
103
132
  "loading": "插件檢測中...",
104
133
  "unknown": "未知插件"
105
134
  },
106
- "setting": "插件設定",
135
+ "setting": "插件設置",
107
136
  "settings": {
108
137
  "indexUrl": {
109
- "title": "市場索引",
110
- "tooltip": "暫不支持線上編輯,請透過部署時環境變數進行設定"
138
+ "title": "外掛市集索引",
139
+ "tooltip": "目前不支援編輯"
111
140
  },
112
- "modalDesc": "配置插件市場的地址後,可以使用自定義的插件市場",
113
- "title": "設定插件市場"
141
+ "modalDesc": "設定外掛市集的網址後,您可以使用自訂的外掛市集",
142
+ "title": "設定外掛市集"
114
143
  },
115
144
  "store": {
145
+ "actions": {
146
+ "confirmUninstall": "即將卸載該插件,卸載後將清除該插件配置,請確認你的操作",
147
+ "detail": "詳情",
148
+ "install": "安裝",
149
+ "manifest": "編輯安裝檔案",
150
+ "settings": "設定",
151
+ "uninstall": "卸載"
152
+ },
153
+ "communityPlugin": "社群外掛",
154
+ "customPlugin": "自訂插件",
116
155
  "empty": "暫無已安裝插件",
117
- "install": "安裝",
118
156
  "installAllPlugins": "安裝全部",
119
- "networkError": "獲取插件商店失敗,請檢測網路連接後重試",
120
- "releasedAt": "發布於 {{createdAt}}",
157
+ "networkError": "獲取插件商店失敗,請檢查網路連線後重試",
158
+ "placeholder": "搜尋插件名稱介紹或關鍵字...",
159
+ "releasedAt": "發佈於 {{createdAt}}",
121
160
  "tabs": {
122
161
  "all": "全部",
123
162
  "installed": "已安裝"
124
163
  },
125
- "title": "插件商店",
126
- "uninstall": "卸載",
127
- "placeholder": "搜尋插件名稱介紹或關鍵字..."
164
+ "title": "插件商店"
128
165
  }
129
166
  }
@@ -85,7 +85,7 @@
85
85
  "waitingForMore": "更多模型正在 <1>計劃接入</1> 中,敬請期待 ✨"
86
86
  },
87
87
  "plugin": {
88
- "addTooltip": "新增自訂外掛",
88
+ "addTooltip": "新增自訂外掛程式",
89
89
  "clearDeprecated": "清除已棄用的外掛",
90
90
  "empty": "目前沒有安裝任何外掛,歡迎前往 <1>外掛商店</1> 探索",
91
91
  "installStatus": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.111.5",
3
+ "version": "0.112.0",
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",
@@ -125,6 +125,7 @@
125
125
  "use-merge-value": "^1",
126
126
  "utility-types": "^3",
127
127
  "uuid": "^9",
128
+ "yaml": "^2",
128
129
  "zod": "^3",
129
130
  "zustand": "^4.4",
130
131
  "zustand-utils": "^1"
@@ -158,6 +159,7 @@
158
159
  "glob": "^10",
159
160
  "husky": "^8",
160
161
  "jsdom": "^23.0.0",
162
+ "just-diff": "^6",
161
163
  "lint-staged": "^15",
162
164
  "lodash": "^4",
163
165
  "markdown-table": "^3",
@@ -18,7 +18,10 @@ const run = async () => {
18
18
  en: path,
19
19
  };
20
20
  const links = {
21
- cn: urlJoin(WIKI_URL, relative(DOCS_DIR, paths.cn).split('/')[1].replace('.zh-CN.md', '')),
21
+ cn: urlJoin(
22
+ WIKI_URL,
23
+ relative(DOCS_DIR, paths.cn).split('/')[1].replace('.zh-CN.md', '.zh-CN'),
24
+ ),
22
25
  en: urlJoin(WIKI_URL, relative(DOCS_DIR, paths.en).split('/')[1].replace('.md', '')),
23
26
  };
24
27
  const titles = {
@@ -60,7 +63,7 @@ const run = async () => {
60
63
  child.links.cn,
61
64
  )}\n`;
62
65
  });
63
- homeContent += `\n\n---\n\n`;
66
+ homeContent += `\n\n<br/>\n\n`;
64
67
  sidebarContent += `\n\n`;
65
68
  });
66
69
 
@@ -1,11 +1,11 @@
1
1
  export default [
2
2
  {
3
3
  dir: 'Usage',
4
- title: '🤯 LobeChat Usage',
4
+ title: '🤯 Usage',
5
5
  },
6
6
  {
7
7
  dir: 'Deployment',
8
- title: '🛳 Self Hosting',
8
+ title: '🛳 Self-Hosting',
9
9
  },
10
10
  {
11
11
  dir: 'Development',
@@ -1,5 +1,6 @@
1
1
  import { consola } from 'consola';
2
2
  import { colors } from 'consola/utils';
3
+ import { diff } from 'just-diff';
3
4
  import { unset } from 'lodash';
4
5
  import { existsSync } from 'node:fs';
5
6
 
@@ -9,7 +10,7 @@ import {
9
10
  localesResourcesFilepath,
10
11
  outputLocaleJsonFilepath,
11
12
  } from './const';
12
- import { diff, readJSON, tagWhite, tagYellow, writeJSON } from './utils';
13
+ import { readJSON, tagWhite, writeJSON } from './utils';
13
14
 
14
15
  export const genDiff = () => {
15
16
  consola.start(`Diff between Dev/Prod local...`);
@@ -22,15 +23,13 @@ export const genDiff = () => {
22
23
  if (!existsSync(filepath)) continue;
23
24
  const prodJSON = readJSON(filepath);
24
25
 
25
- const diffKeys = diff(devJSON, prodJSON);
26
-
27
- if (diffKeys.length === 0) {
26
+ const diffResult = diff(prodJSON, devJSON as any);
27
+ const remove = diffResult.filter((item) => item.op === 'remove');
28
+ if (remove.length === 0) {
28
29
  consola.success(tagWhite(ns), colors.gray(filepath));
29
30
  continue;
30
31
  }
31
32
 
32
- consola.warn(tagYellow(ns), diffKeys);
33
-
34
33
  const clearLocals = [];
35
34
 
36
35
  for (const locale of [i18nConfig.entryLocale, ...i18nConfig.outputLocales]) {
@@ -38,8 +37,8 @@ export const genDiff = () => {
38
37
  if (!existsSync(localeFilepath)) continue;
39
38
  const localeJSON = readJSON(localeFilepath);
40
39
 
41
- for (const key of diffKeys) {
42
- unset(localeJSON, key);
40
+ for (const item of remove) {
41
+ unset(localeJSON, item.path);
43
42
  }
44
43
 
45
44
  writeJSON(localeFilepath, localeJSON);
@@ -1,7 +1,6 @@
1
1
  import { consola } from 'consola';
2
2
  import { colors } from 'consola/utils';
3
3
  import { tocForResources } from 'i18next-resources-for-ts';
4
- import { isObject } from 'lodash';
5
4
  import { readFileSync, writeFileSync } from 'node:fs';
6
5
  import { resolve } from 'node:path';
7
6
 
@@ -58,19 +57,6 @@ export const genToc = (files: string[], locale: string) => {
58
57
  return toc;
59
58
  };
60
59
 
61
- export const diff = (obj1: any, obj2: any, prefix: string = ''): string[] => {
62
- let result: string[] = [];
63
- for (const key in obj1) {
64
- if (!obj2[key]) continue;
65
- if (isObject(obj1[key]) && isObject(obj2[key])) {
66
- result = [...result, ...diff(obj1[key], obj2[key], `${prefix}${key}.`)];
67
- } else if (obj1[key] !== obj2[key]) {
68
- result.push(`${prefix}${key}`);
69
- }
70
- }
71
- return result;
72
- };
73
-
74
60
  export const tagBlue = (text: string) => colors.bgBlueBright(colors.black(` ${text} `));
75
61
  export const tagYellow = (text: string) => colors.bgYellowBright(colors.black(` ${text} `));
76
62
  export const tagGreen = (text: string) => colors.bgGreenBright(colors.black(` ${text} `));
@@ -6,18 +6,16 @@ import { fetchPluginIndex, genLink, genTags, readReadme, updateReadme, writeRead
6
6
 
7
7
  const genPluginTable = (data: DataItem[], lang: string) => {
8
8
  const isCN = lang === 'zh-CN';
9
- const content = data
10
- .filter((item) => item.author === 'LobeHub')
11
- .map((item) => [
12
- [
13
- genLink(item.meta.title, PLGUIN_URL),
14
- `<sup>By **${item.author}** on **${item.createAt}**</sup>`,
15
- ].join('<br/>'),
16
- genLink(item.homepage.split('github.com/')[1], item.homepage),
17
- [item.meta.description, genTags(item.meta.tags)].join('<br/>'),
18
- ]);
9
+ const content = data.map((item) => [
10
+ [
11
+ genLink(item.meta.title, PLGUIN_URL),
12
+ `<sup>By **${item.author}** on **${item.createAt}**</sup>`,
13
+ ].join('<br/>'),
14
+ genLink(item.homepage.split('github.com/')[1], item.homepage),
15
+ [item.meta.description, genTags(item.meta.tags)].join('<br/>'),
16
+ ]);
19
17
  return markdownTable([
20
- isCN ? ['官方插件', '仓库', '插件描述'] : ['Official Plugin', 'Repository', 'Description'],
18
+ isCN ? ['最近新增', '仓库', '插件描述'] : ['Recent Submits', 'Repository', 'Description'],
21
19
  ...content,
22
20
  ]);
23
21
  };
@@ -1,7 +1,5 @@
1
- import { createLobeChatPluginGateway } from '@lobehub/chat-plugins-gateway';
1
+ import { createGatewayOnEdgeRuntime } from '@lobehub/chat-plugins-gateway';
2
2
 
3
3
  import { PLUGINS_INDEX_URL } from '@/const/url';
4
4
 
5
- export const runtime = 'edge';
6
-
7
- export const POST = createLobeChatPluginGateway({ pluginsIndexUrl: PLUGINS_INDEX_URL });
5
+ export const POST = createGatewayOnEdgeRuntime({ pluginsIndexUrl: PLUGINS_INDEX_URL });
@@ -0,0 +1,10 @@
1
+ export const runtime = 'edge';
2
+
3
+ /**
4
+ * just for a proxy
5
+ */
6
+ export const POST = async (req: Request) => {
7
+ const url = await req.text();
8
+
9
+ return fetch(url);
10
+ };
@@ -1,15 +1,14 @@
1
- import { Checkbox, Tag } from 'antd';
1
+ import { Checkbox } from 'antd';
2
2
  import { memo } from 'react';
3
- import { useTranslation } from 'react-i18next';
4
3
  import { Flexbox } from 'react-layout-kit';
5
4
 
5
+ import PluginTag from '@/features/PluginStore/PluginItem/PluginTag';
6
6
  import { useSessionStore } from '@/store/session';
7
7
  import { agentSelectors } from '@/store/session/selectors';
8
8
  import { useToolStore } from '@/store/tool';
9
9
  import { customPluginSelectors } from '@/store/tool/selectors';
10
10
 
11
11
  const ToolItem = memo<{ identifier: string; label: string }>(({ identifier, label }) => {
12
- const { t } = useTranslation('plugin');
13
12
  const [checked, togglePlugin] = useSessionStore((s) => [
14
13
  agentSelectors.currentAgentPlugins(s).includes(identifier),
15
14
  s.togglePlugin,
@@ -30,11 +29,7 @@ const ToolItem = memo<{ identifier: string; label: string }>(({ identifier, labe
30
29
  >
31
30
  <Flexbox align={'center'} gap={8} horizontal>
32
31
  {label}
33
- {isCustom && (
34
- <Tag bordered={false} color={'gold'}>
35
- {t('list.item.local.title')}
36
- </Tag>
37
- )}
32
+ {isCustom && <PluginTag showText={false} type={'customPlugin'} />}
38
33
  </Flexbox>
39
34
  <Checkbox
40
35
  checked={checked}
@@ -2,7 +2,7 @@ import { ActionIcon, Avatar, Icon } from '@lobehub/ui';
2
2
  import { Dropdown } from 'antd';
3
3
  import { createStyles } from 'antd-style';
4
4
  import isEqual from 'fast-deep-equal';
5
- import { ArrowRight, PencilRuler, Store, ToyBrick } from 'lucide-react';
5
+ import { ArrowRight, Blocks, Store, ToyBrick } from 'lucide-react';
6
6
  import { memo, useState } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
8
8
  import { Flexbox } from 'react-layout-kit';
@@ -103,10 +103,10 @@ const Tools = memo(() => {
103
103
  e.domEvent.preventDefault();
104
104
  },
105
105
  }}
106
- placement={'topLeft'}
106
+ placement={'top'}
107
107
  trigger={['click']}
108
108
  >
109
- <ActionIcon icon={PencilRuler} placement={'bottom'} title={t('tools.title')} />
109
+ <ActionIcon icon={Blocks} placement={'bottom'} title={t('tools.title')} />
110
110
  </Dropdown>
111
111
  <PluginStore open={open} setOpen={setOpen} />
112
112
  </>
@@ -37,6 +37,12 @@ export const renderErrorMessages: ChatListProps['renderErrorMessages'] = {
37
37
  [PluginErrorType.PluginServerError]: {
38
38
  Render: PluginError,
39
39
  },
40
+ [PluginErrorType.PluginGatewayError]: {
41
+ Render: PluginError,
42
+ },
43
+ [PluginErrorType.PluginOpenApiInitError]: {
44
+ Render: PluginError,
45
+ },
40
46
  [PluginErrorType.PluginSettingsInvalid]: {
41
47
  Render: PluginSettings,
42
48
  config: {
@@ -18,7 +18,7 @@ export const FunctionMessage = memo<ChatMessage>(({ id, content, plugin }) => {
18
18
  const [showRender, setShow] = useState(true);
19
19
 
20
20
  return (
21
- <Flexbox gap={12} id={id}>
21
+ <Flexbox gap={12} id={id} width={'100%'}>
22
22
  <Inspector showRender={showRender} {...fcProps} setShow={setShow} />
23
23
  {showRender && (
24
24
  <PluginRender
@@ -2,17 +2,19 @@ import { ActionIcon } from '@lobehub/ui';
2
2
  import { LucideSettings } from 'lucide-react';
3
3
  import { memo, useState } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
+ import PluginDetailModal from 'src/features/PluginDetailModal';
5
6
 
6
- import PluginSettingsModal from '@/features/PluginSettingsModal';
7
- import { useToolStore } from '@/store/tool';
7
+ import { pluginHelpers, useToolStore } from '@/store/tool';
8
8
  import { pluginSelectors } from '@/store/tool/selectors';
9
9
 
10
10
  const Settings = memo<{ id: string }>(({ id }) => {
11
11
  const item = useToolStore(pluginSelectors.getPluginManifestById(id));
12
12
  const [open, setOpen] = useState(false);
13
13
  const { t } = useTranslation('plugin');
14
+ const hasSettings = pluginHelpers.isSettingSchemaNonEmpty(item?.settings);
15
+
14
16
  return (
15
- item?.settings && (
17
+ hasSettings && (
16
18
  <>
17
19
  <ActionIcon
18
20
  icon={LucideSettings}
@@ -21,13 +23,13 @@ const Settings = memo<{ id: string }>(({ id }) => {
21
23
  }}
22
24
  title={t('setting')}
23
25
  />
24
- <PluginSettingsModal
26
+ <PluginDetailModal
25
27
  id={id}
26
28
  onClose={() => {
27
29
  setOpen(false);
28
30
  }}
29
31
  open={open}
30
- schema={item.settings}
32
+ schema={item?.settings}
31
33
  />
32
34
  </>
33
35
  )
@@ -50,7 +50,7 @@ const Inspector = memo<InspectorProps>(
50
50
  const pluginMeta = useToolStore(pluginSelectors.getPluginMetaById(id), isEqual);
51
51
  const showRightAction = useToolStore(pluginSelectors.isPluginHasUI(id));
52
52
  const pluginAvatar = pluginHelpers.getPluginAvatar(pluginMeta);
53
- const pluginTitle = pluginHelpers.getPluginTitle(pluginMeta) ?? t('plugins.unknown');
53
+ const pluginTitle = pluginHelpers.getPluginTitle(pluginMeta) ?? t('plugins.loading');
54
54
 
55
55
  const avatar = pluginAvatar ? (
56
56
  <Avatar avatar={pluginAvatar} size={32} />
@@ -80,7 +80,7 @@ const Inspector = memo<InspectorProps>(
80
80
  ) : (
81
81
  avatar
82
82
  )}
83
- {loading ? t('plugins.loading') : pluginTitle}
83
+ {pluginTitle}
84
84
  {showRightAction && <Icon icon={showRender ? LucideChevronUp : LucideChevronDown} />}
85
85
  </Flexbox>
86
86
  {
@@ -72,7 +72,7 @@ export interface PluginDefaultTypeProps {
72
72
  name?: string;
73
73
  }
74
74
 
75
- const PluginDefaultType = memo<PluginDefaultTypeProps>(({ content, name }) => {
75
+ const PluginDefaultType = memo<PluginDefaultTypeProps>(({ content, name, loading }) => {
76
76
  const manifest = useToolStore(pluginSelectors.getPluginManifestById(name || ''));
77
77
  let isJSON = true;
78
78
  try {
@@ -85,9 +85,11 @@ const PluginDefaultType = memo<PluginDefaultTypeProps>(({ content, name }) => {
85
85
 
86
86
  if (!isJSON) {
87
87
  return (
88
- <Flexbox gap={8}>
89
- <Loading />
90
- </Flexbox>
88
+ loading && (
89
+ <Flexbox gap={8}>
90
+ <Loading />
91
+ </Flexbox>
92
+ )
91
93
  );
92
94
  }
93
95
 
@@ -13,14 +13,14 @@ export interface PluginRenderProps {
13
13
  type?: LobePluginType;
14
14
  }
15
15
 
16
- const PluginRender = memo<PluginRenderProps>(({ content, id, payload, name, type }) => {
16
+ const PluginRender = memo<PluginRenderProps>(({ content, id, payload, name, type, loading }) => {
17
17
  switch (type) {
18
18
  case 'standalone': {
19
19
  return <Standalone id={id} name={name} payload={payload} />;
20
20
  }
21
21
 
22
22
  default: {
23
- return <DefaultType content={content} name={name} />;
23
+ return <DefaultType content={content} loading={loading} name={name} />;
24
24
  }
25
25
  }
26
26
  });
@@ -2,7 +2,7 @@ import { Button } from 'antd';
2
2
  import { memo } from 'react';
3
3
  import { useTranslation } from 'react-i18next';
4
4
 
5
- const ExportConfigButton = memo<{ primary?: boolean, state: any; }>(({ state, primary }) => {
5
+ const ExportConfigButton = memo<{ primary?: boolean; state: any }>(({ state, primary }) => {
6
6
  const { t } = useTranslation('migration');
7
7
 
8
8
  const exportData = () => {
@@ -55,6 +55,7 @@ const AgentModalInner = memo(() => {
55
55
  },
56
56
  ]}
57
57
  onChange={setTab}
58
+ variant={'compact'}
58
59
  />
59
60
  </Flexbox>
60
61
  <Flexbox style={{ padding: 16 }}>
@@ -29,15 +29,7 @@ export const useStyles = createStyles(({ css, token, prefixCls, stylish }) => ({
29
29
  `,
30
30
  markdown: stylish.markdownInChat,
31
31
  nav: css`
32
- padding-top: 4px;
33
-
34
- .${prefixCls}-tabs-tab {
35
- margin: 4px !important;
36
-
37
- + .${prefixCls}-tabs-tab {
38
- margin: 4px !important;
39
- }
40
- }
32
+ padding-top: 8px;
41
33
  `,
42
34
  title: css`
43
35
  font-size: 20px;