@lobehub/lobehub 2.1.4 → 2.1.5

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 CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 2.1.5](https://github.com/lobehub/lobe-chat/compare/v2.1.4...v2.1.5)
6
+
7
+ <sup>Released on **2026-01-31**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Slove the group member agents cant set skills problem.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Slove the group member agents cant set skills problem, closes [#12021](https://github.com/lobehub/lobe-chat/issues/12021) ([2302940](https://github.com/lobehub/lobe-chat/commit/2302940))
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
+
5
30
  ### [Version 2.1.4](https://github.com/lobehub/lobe-chat/compare/v2.1.3...v2.1.4)
6
31
 
7
32
  <sup>Released on **2026-01-31**</sup>
package/changelog/v2.json CHANGED
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "fixes": [
5
+ "Slove the group member agents cant set skills problem."
6
+ ]
7
+ },
8
+ "date": "2026-01-31",
9
+ "version": "2.1.5"
10
+ },
2
11
  {
3
12
  "children": {
4
13
  "improvements": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.1.4",
3
+ "version": "2.1.5",
4
4
  "description": "LobeHub - an open-source,comprehensive AI Agent 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",
@@ -15,6 +15,11 @@ const POLL_INTERVAL_MS = 1000; // 每秒轮询一次
15
15
  const POLL_TIMEOUT_MS = 15_000; // 15 秒超时
16
16
 
17
17
  interface KlavisServerItemProps {
18
+ /**
19
+ * Optional agent ID to use instead of currentAgentConfig
20
+ * Used in group profile to specify which member's plugins to toggle
21
+ */
22
+ agentId?: string;
18
23
  /**
19
24
  * Identifier used for storage (e.g., 'google-calendar')
20
25
  */
@@ -28,7 +33,7 @@ interface KlavisServerItemProps {
28
33
  }
29
34
 
30
35
  const KlavisServerItem = memo<KlavisServerItemProps>(
31
- ({ identifier, label, server, serverName }) => {
36
+ ({ identifier, label, server, serverName, agentId }) => {
32
37
  const { t } = useTranslation('setting');
33
38
  const [isConnecting, setIsConnecting] = useState(false);
34
39
  const [isToggling, setIsToggling] = useState(false);
@@ -43,6 +48,10 @@ const KlavisServerItem = memo<KlavisServerItemProps>(
43
48
  const createKlavisServer = useToolStore((s) => s.createKlavisServer);
44
49
  const refreshKlavisServerTools = useToolStore((s) => s.refreshKlavisServerTools);
45
50
 
51
+ // Get effective agent ID (agentId prop or current active agent)
52
+ const activeAgentId = useAgentStore((s) => s.activeAgentId);
53
+ const effectiveAgentId = agentId || activeAgentId || '';
54
+
46
55
  // 清理所有定时器
47
56
  const cleanup = useCallback(() => {
48
57
  if (windowCheckIntervalRef.current) {
@@ -162,10 +171,24 @@ const KlavisServerItem = memo<KlavisServerItemProps>(
162
171
 
163
172
  // Get plugin ID for this server (使用 identifier 作为 pluginId)
164
173
  const pluginId = server ? server.identifier : '';
165
- const [checked, togglePlugin] = useAgentStore((s) => [
166
- agentSelectors.currentAgentPlugins(s).includes(pluginId),
167
- s.togglePlugin,
168
- ]);
174
+ const plugins =
175
+ useAgentStore(agentSelectors.getAgentConfigById(effectiveAgentId))?.plugins || [];
176
+ const checked = plugins.includes(pluginId);
177
+ const updateAgentConfigById = useAgentStore((s) => s.updateAgentConfigById);
178
+
179
+ // Toggle plugin for the effective agent
180
+ const togglePlugin = useCallback(
181
+ async (pluginIdToToggle: string) => {
182
+ if (!effectiveAgentId) return;
183
+ const currentPlugins = plugins;
184
+ const hasPlugin = currentPlugins.includes(pluginIdToToggle);
185
+ const newPlugins = hasPlugin
186
+ ? currentPlugins.filter((id) => id !== pluginIdToToggle)
187
+ : [...currentPlugins, pluginIdToToggle];
188
+ await updateAgentConfigById(effectiveAgentId, { plugins: newPlugins });
189
+ },
190
+ [effectiveAgentId, plugins, updateAgentConfigById],
191
+ );
169
192
 
170
193
  const handleConnect = async () => {
171
194
  if (!userId) {
@@ -13,6 +13,11 @@ const POLL_INTERVAL_MS = 1000;
13
13
  const POLL_TIMEOUT_MS = 15_000;
14
14
 
15
15
  interface LobehubSkillServerItemProps {
16
+ /**
17
+ * Optional agent ID to use instead of currentAgentConfig
18
+ * Used in group profile to specify which member's plugins to toggle
19
+ */
20
+ agentId?: string;
16
21
  /**
17
22
  * Display label for the provider
18
23
  */
@@ -23,7 +28,7 @@ interface LobehubSkillServerItemProps {
23
28
  provider: string;
24
29
  }
25
30
 
26
- const LobehubSkillServerItem = memo<LobehubSkillServerItemProps>(({ provider, label }) => {
31
+ const LobehubSkillServerItem = memo<LobehubSkillServerItemProps>(({ provider, label, agentId }) => {
27
32
  const { t } = useTranslation('setting');
28
33
  const [isConnecting, setIsConnecting] = useState(false);
29
34
  const [isToggling, setIsToggling] = useState(false);
@@ -38,6 +43,10 @@ const LobehubSkillServerItem = memo<LobehubSkillServerItemProps>(({ provider, la
38
43
  const checkStatus = useToolStore((s) => s.checkLobehubSkillStatus);
39
44
  const getAuthorizeUrl = useToolStore((s) => s.getLobehubSkillAuthorizeUrl);
40
45
 
46
+ // Get effective agent ID (agentId prop or current active agent)
47
+ const activeAgentId = useAgentStore((s) => s.activeAgentId);
48
+ const effectiveAgentId = agentId || activeAgentId || '';
49
+
41
50
  const cleanup = useCallback(() => {
42
51
  if (windowCheckIntervalRef.current) {
43
52
  clearInterval(windowCheckIntervalRef.current);
@@ -129,10 +138,23 @@ const LobehubSkillServerItem = memo<LobehubSkillServerItemProps>(({ provider, la
129
138
  );
130
139
 
131
140
  const pluginId = server ? server.identifier : '';
132
- const [checked, togglePlugin] = useAgentStore((s) => [
133
- agentSelectors.currentAgentPlugins(s).includes(pluginId),
134
- s.togglePlugin,
135
- ]);
141
+ const plugins = useAgentStore(agentSelectors.getAgentConfigById(effectiveAgentId))?.plugins || [];
142
+ const checked = plugins.includes(pluginId);
143
+ const updateAgentConfigById = useAgentStore((s) => s.updateAgentConfigById);
144
+
145
+ // Toggle plugin for the effective agent
146
+ const togglePlugin = useCallback(
147
+ async (pluginIdToToggle: string) => {
148
+ if (!effectiveAgentId) return;
149
+ const currentPlugins = plugins;
150
+ const hasPlugin = currentPlugins.includes(pluginIdToToggle);
151
+ const newPlugins = hasPlugin
152
+ ? currentPlugins.filter((id) => id !== pluginIdToToggle)
153
+ : [...currentPlugins, pluginIdToToggle];
154
+ await updateAgentConfigById(effectiveAgentId, { plugins: newPlugins });
155
+ },
156
+ [effectiveAgentId, plugins, updateAgentConfigById],
157
+ );
136
158
 
137
159
  // Listen for OAuth success message from popup window
138
160
  useEffect(() => {
@@ -156,9 +178,10 @@ const LobehubSkillServerItem = memo<LobehubSkillServerItemProps>(({ provider, la
156
178
  .lobehubSkillServers?.find((s) => s.identifier === provider);
157
179
  if (latestServer?.status === LobehubSkillStatus.CONNECTED) {
158
180
  const newPluginId = latestServer.identifier;
159
- const isAlreadyEnabled = agentSelectors
160
- .currentAgentPlugins(useAgentStore.getState())
161
- .includes(newPluginId);
181
+ const currentAgentPlugins =
182
+ agentSelectors.getAgentConfigById(effectiveAgentId)(useAgentStore.getState())
183
+ ?.plugins || [];
184
+ const isAlreadyEnabled = currentAgentPlugins.includes(newPluginId);
162
185
  if (!isAlreadyEnabled) {
163
186
  console.log('[LobehubSkill] Auto-enabling plugin:', newPluginId);
164
187
  togglePlugin(newPluginId);
@@ -169,7 +192,7 @@ const LobehubSkillServerItem = memo<LobehubSkillServerItemProps>(({ provider, la
169
192
 
170
193
  window.addEventListener('message', handleMessage);
171
194
  return () => window.removeEventListener('message', handleMessage);
172
- }, [provider, cleanup, checkStatus, togglePlugin]);
195
+ }, [provider, cleanup, checkStatus, togglePlugin, effectiveAgentId]);
173
196
 
174
197
  const handleConnect = async () => {
175
198
  // 只有已连接状态才阻止重新连接
@@ -176,6 +176,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
176
176
  key: type.identifier,
177
177
  label: (
178
178
  <KlavisServerItem
179
+ agentId={agentId}
179
180
  identifier={type.identifier}
180
181
  label={type.label}
181
182
  server={getServerByName(type.identifier)}
@@ -184,7 +185,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
184
185
  ),
185
186
  }))
186
187
  : [],
187
- [isKlavisEnabledInEnv, allKlavisServers, installedKlavisIds, recommendedKlavisIds],
188
+ [isKlavisEnabledInEnv, allKlavisServers, installedKlavisIds, recommendedKlavisIds, agentId],
188
189
  );
189
190
 
190
191
  // LobeHub Skill Provider 列表项 - 只展示已安装或推荐的
@@ -197,10 +198,22 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
197
198
  ).map((provider) => ({
198
199
  icon: <LobehubSkillIcon icon={provider.icon} label={provider.label} />,
199
200
  key: provider.id, // 使用 provider.id 作为 key,与 pluginId 保持一致
200
- label: <LobehubSkillServerItem label={provider.label} provider={provider.id} />,
201
+ label: (
202
+ <LobehubSkillServerItem
203
+ agentId={agentId}
204
+ label={provider.label}
205
+ provider={provider.id}
206
+ />
207
+ ),
201
208
  }))
202
209
  : [],
203
- [isLobehubSkillEnabled, allLobehubSkillServers, installedLobehubIds, recommendedLobehubIds],
210
+ [
211
+ isLobehubSkillEnabled,
212
+ allLobehubSkillServers,
213
+ installedLobehubIds,
214
+ recommendedLobehubIds,
215
+ agentId,
216
+ ],
204
217
  );
205
218
 
206
219
  // Builtin 工具列表项(不包含 Klavis 和 LobeHub Skill)
@@ -271,6 +271,7 @@ const AgentTool = memo<AgentToolProps>(
271
271
  key: type.identifier,
272
272
  label: (
273
273
  <KlavisServerItem
274
+ agentId={effectiveAgentId}
274
275
  identifier={type.identifier}
275
276
  label={type.label}
276
277
  server={getServerByName(type.identifier)}
@@ -279,7 +280,7 @@ const AgentTool = memo<AgentToolProps>(
279
280
  ),
280
281
  }))
281
282
  : [],
282
- [isKlavisEnabledInEnv, allKlavisServers],
283
+ [isKlavisEnabledInEnv, allKlavisServers, effectiveAgentId],
283
284
  );
284
285
 
285
286
  // LobeHub Skill Provider 列表项
@@ -289,10 +290,16 @@ const AgentTool = memo<AgentToolProps>(
289
290
  ? LOBEHUB_SKILL_PROVIDERS.map((provider) => ({
290
291
  icon: <LobehubSkillIcon icon={provider.icon} label={provider.label} />,
291
292
  key: provider.id, // 使用 provider.id 作为 key,与 pluginId 保持一致
292
- label: <LobehubSkillServerItem label={provider.label} provider={provider.id} />,
293
+ label: (
294
+ <LobehubSkillServerItem
295
+ agentId={effectiveAgentId}
296
+ label={provider.label}
297
+ provider={provider.id}
298
+ />
299
+ ),
293
300
  }))
294
301
  : [],
295
- [isLobehubSkillEnabled, allLobehubSkillServers],
302
+ [isLobehubSkillEnabled, allLobehubSkillServers, effectiveAgentId],
296
303
  );
297
304
 
298
305
  // Handle plugin remove via Tag close - use byId actions