@lobehub/lobehub 2.0.0-next.284 → 2.0.0-next.286
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 +50 -0
- package/changelog/v1.json +18 -0
- package/locales/en-US/setting.json +1 -0
- package/locales/en-US/subscription.json +2 -0
- package/locales/zh-CN/setting.json +1 -0
- package/locales/zh-CN/subscription.json +2 -0
- package/package.json +1 -1
- package/packages/builtin-tool-agent-builder/src/ExecutionRuntime/index.ts +79 -2
- package/packages/builtin-tool-agent-builder/src/client/Intervention/InstallPlugin.tsx +66 -5
- package/packages/builtin-tool-agent-builder/src/client/Render/InstallPlugin.tsx +12 -4
- package/packages/builtin-tool-agent-builder/src/manifest.ts +3 -2
- package/packages/builtin-tool-agent-builder/src/systemRole.ts +8 -8
- package/packages/builtin-tool-agent-builder/src/types.ts +7 -3
- package/packages/business/const/src/index.ts +0 -3
- package/packages/context-engine/src/providers/AgentBuilderContextInjector.ts +20 -4
- package/packages/context-engine/src/providers/GroupAgentBuilderContextInjector.ts +18 -2
- package/packages/model-bank/src/aiModels/lobehub.ts +20 -1
- package/packages/model-runtime/src/providers/fal/index.test.ts +176 -1
- package/packages/model-runtime/src/providers/fal/index.ts +3 -1
- package/src/app/[variants]/(main)/agent/features/Conversation/AgentWelcome/AddButton.tsx +2 -1
- package/src/app/[variants]/(main)/agent/features/Conversation/Header/ShareButton/index.tsx +5 -3
- package/src/app/[variants]/(main)/agent/features/Conversation/MainChatInput/MessageFromUrl.tsx +57 -9
- package/src/app/[variants]/(main)/agent/profile/features/Header/AgentPublishButton/PublishButton.tsx +5 -8
- package/src/app/[variants]/(main)/agent/profile/features/Header/index.tsx +0 -2
- package/src/app/[variants]/(main)/agent/profile/features/ProfileEditor/index.tsx +2 -0
- package/src/app/[variants]/(main)/community/(detail)/provider/features/Details/Nav.tsx +27 -18
- package/src/app/[variants]/(main)/group/features/Conversation/Header/ShareButton/index.tsx +5 -3
- package/src/app/[variants]/(main)/group/features/Conversation/MainChatInput/MessageFromUrl.tsx +24 -10
- package/src/app/[variants]/onboarding/_layout/style.ts +10 -20
- package/src/features/ProfileEditor/AgentTool.tsx +68 -12
- package/src/features/ProfileEditor/PluginTag.tsx +56 -3
- package/src/locales/default/setting.ts +1 -0
- package/src/locales/default/subscription.ts +2 -0
- package/src/services/chat/index.ts +24 -1
- package/src/services/chat/mecha/contextEngineering.ts +28 -2
- package/src/store/chat/slices/plugin/actions/pluginTypes.ts +11 -1
- package/src/store/user/slices/settings/action.test.ts +25 -0
- package/src/store/user/slices/settings/action.ts +11 -0
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
KLAVIS_SERVER_TYPES,
|
|
5
|
+
type KlavisServerType,
|
|
6
|
+
LOBEHUB_SKILL_PROVIDERS,
|
|
7
|
+
type LobehubSkillProviderType,
|
|
8
|
+
} from '@lobechat/const';
|
|
4
9
|
import { Avatar, Button, Flexbox, Icon, type ItemType, Segmented } from '@lobehub/ui';
|
|
5
10
|
import { createStaticStyles, cssVar } from 'antd-style';
|
|
6
11
|
import isEqual from 'fast-deep-equal';
|
|
@@ -10,6 +15,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
10
15
|
|
|
11
16
|
import PluginAvatar from '@/components/Plugins/PluginAvatar';
|
|
12
17
|
import KlavisServerItem from '@/features/ChatInput/ActionBar/Tools/KlavisServerItem';
|
|
18
|
+
import LobehubSkillServerItem from '@/features/ChatInput/ActionBar/Tools/LobehubSkillServerItem';
|
|
13
19
|
import ToolItem from '@/features/ChatInput/ActionBar/Tools/ToolItem';
|
|
14
20
|
import ActionDropdown from '@/features/ChatInput/ActionBar/components/ActionDropdown';
|
|
15
21
|
import PluginStore from '@/features/PluginStore';
|
|
@@ -22,6 +28,7 @@ import { useToolStore } from '@/store/tool';
|
|
|
22
28
|
import {
|
|
23
29
|
builtinToolSelectors,
|
|
24
30
|
klavisStoreSelectors,
|
|
31
|
+
lobehubSkillStoreSelectors,
|
|
25
32
|
pluginSelectors,
|
|
26
33
|
} from '@/store/tool/selectors';
|
|
27
34
|
import { type LobeToolMetaWithAvailability } from '@/store/tool/slices/builtin/selectors';
|
|
@@ -81,6 +88,19 @@ const KlavisIcon = memo<Pick<KlavisServerType, 'icon' | 'label'>>(({ icon, label
|
|
|
81
88
|
return <Icon className={styles.icon} fill={cssVar.colorText} icon={icon} size={18} />;
|
|
82
89
|
});
|
|
83
90
|
|
|
91
|
+
/**
|
|
92
|
+
* LobeHub Skill Provider 图标组件
|
|
93
|
+
*/
|
|
94
|
+
const LobehubSkillIcon = memo<Pick<LobehubSkillProviderType, 'icon' | 'label'>>(
|
|
95
|
+
({ icon, label }) => {
|
|
96
|
+
if (typeof icon === 'string') {
|
|
97
|
+
return <img alt={label} className={styles.icon} height={18} src={icon} width={18} />;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return <Icon className={styles.icon} fill={cssVar.colorText} icon={icon} size={18} />;
|
|
101
|
+
},
|
|
102
|
+
);
|
|
103
|
+
|
|
84
104
|
export interface AgentToolProps {
|
|
85
105
|
/**
|
|
86
106
|
* Optional agent ID to use instead of currentAgentConfig
|
|
@@ -125,12 +145,18 @@ const AgentTool = memo<AgentToolProps>(
|
|
|
125
145
|
);
|
|
126
146
|
|
|
127
147
|
// Web browsing uses searchMode instead of plugins array - use byId selector
|
|
128
|
-
const isSearchEnabled = useAgentStore(
|
|
148
|
+
const isSearchEnabled = useAgentStore(
|
|
149
|
+
chatConfigByIdSelectors.isEnableSearchById(effectiveAgentId),
|
|
150
|
+
);
|
|
129
151
|
|
|
130
152
|
// Klavis 相关状态
|
|
131
153
|
const allKlavisServers = useToolStore(klavisStoreSelectors.getServers, isEqual);
|
|
132
154
|
const isKlavisEnabledInEnv = useServerConfigStore(serverConfigSelectors.enableKlavis);
|
|
133
155
|
|
|
156
|
+
// LobeHub Skill 相关状态
|
|
157
|
+
const allLobehubSkillServers = useToolStore(lobehubSkillStoreSelectors.getServers, isEqual);
|
|
158
|
+
const isLobehubSkillEnabled = useServerConfigStore(serverConfigSelectors.enableLobehubSkill);
|
|
159
|
+
|
|
134
160
|
// Plugin store modal state
|
|
135
161
|
const [modalOpen, setModalOpen] = useState(false);
|
|
136
162
|
const [updating, setUpdating] = useState(false);
|
|
@@ -140,10 +166,12 @@ const AgentTool = memo<AgentToolProps>(
|
|
|
140
166
|
const isInitializedRef = useRef(false);
|
|
141
167
|
|
|
142
168
|
// Fetch plugins
|
|
143
|
-
const [useFetchPluginStore, useFetchUserKlavisServers] =
|
|
144
|
-
s
|
|
145
|
-
|
|
146
|
-
|
|
169
|
+
const [useFetchPluginStore, useFetchUserKlavisServers, useFetchLobehubSkillConnections] =
|
|
170
|
+
useToolStore((s) => [
|
|
171
|
+
s.useFetchPluginStore,
|
|
172
|
+
s.useFetchUserKlavisServers,
|
|
173
|
+
s.useFetchLobehubSkillConnections,
|
|
174
|
+
]);
|
|
147
175
|
useFetchPluginStore();
|
|
148
176
|
useFetchInstalledPlugins();
|
|
149
177
|
useCheckPluginsIsInstalled(plugins);
|
|
@@ -151,6 +179,9 @@ const AgentTool = memo<AgentToolProps>(
|
|
|
151
179
|
// 使用 SWR 加载用户的 Klavis 集成(从数据库)
|
|
152
180
|
useFetchUserKlavisServers(isKlavisEnabledInEnv);
|
|
153
181
|
|
|
182
|
+
// 使用 SWR 加载用户的 LobeHub Skill 连接
|
|
183
|
+
useFetchLobehubSkillConnections(isLobehubSkillEnabled);
|
|
184
|
+
|
|
154
185
|
// Toggle web browsing via searchMode - use byId action
|
|
155
186
|
const toggleWebBrowsing = useCallback(async () => {
|
|
156
187
|
if (!effectiveAgentId) return;
|
|
@@ -270,6 +301,19 @@ const AgentTool = memo<AgentToolProps>(
|
|
|
270
301
|
[isKlavisEnabledInEnv, allKlavisServers],
|
|
271
302
|
);
|
|
272
303
|
|
|
304
|
+
// LobeHub Skill Provider 列表项
|
|
305
|
+
const lobehubSkillItems = useMemo(
|
|
306
|
+
() =>
|
|
307
|
+
isLobehubSkillEnabled
|
|
308
|
+
? LOBEHUB_SKILL_PROVIDERS.map((provider) => ({
|
|
309
|
+
icon: <LobehubSkillIcon icon={provider.icon} label={provider.label} />,
|
|
310
|
+
key: provider.id, // 使用 provider.id 作为 key,与 pluginId 保持一致
|
|
311
|
+
label: <LobehubSkillServerItem label={provider.label} provider={provider.id} />,
|
|
312
|
+
}))
|
|
313
|
+
: [],
|
|
314
|
+
[isLobehubSkillEnabled, allLobehubSkillServers],
|
|
315
|
+
);
|
|
316
|
+
|
|
273
317
|
// Handle plugin remove via Tag close - use byId actions
|
|
274
318
|
const handleRemovePlugin =
|
|
275
319
|
(
|
|
@@ -292,7 +336,7 @@ const AgentTool = memo<AgentToolProps>(
|
|
|
292
336
|
(id) => !builtinList.some((b) => b.identifier === id),
|
|
293
337
|
).length;
|
|
294
338
|
|
|
295
|
-
// 合并 builtin
|
|
339
|
+
// 合并 builtin 工具、LobeHub Skill Providers 和 Klavis 服务器
|
|
296
340
|
const builtinItems = useMemo(
|
|
297
341
|
() => [
|
|
298
342
|
// 原有的 builtin 工具
|
|
@@ -312,10 +356,12 @@ const AgentTool = memo<AgentToolProps>(
|
|
|
312
356
|
/>
|
|
313
357
|
),
|
|
314
358
|
})),
|
|
359
|
+
// LobeHub Skill Providers
|
|
360
|
+
...lobehubSkillItems,
|
|
315
361
|
// Klavis 服务器
|
|
316
362
|
...klavisServerItems,
|
|
317
363
|
],
|
|
318
|
-
[filteredBuiltinList, klavisServerItems, isToolEnabled, handleToggleTool],
|
|
364
|
+
[filteredBuiltinList, klavisServerItems, lobehubSkillItems, isToolEnabled, handleToggleTool],
|
|
319
365
|
);
|
|
320
366
|
|
|
321
367
|
// Plugin items for dropdown
|
|
@@ -413,8 +459,17 @@ const AgentTool = memo<AgentToolProps>(
|
|
|
413
459
|
plugins.includes(item.key as string),
|
|
414
460
|
);
|
|
415
461
|
|
|
416
|
-
//
|
|
417
|
-
const
|
|
462
|
+
// 已连接的 LobeHub Skill Providers
|
|
463
|
+
const connectedLobehubSkillItems = lobehubSkillItems.filter((item) =>
|
|
464
|
+
plugins.includes(item.key as string),
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
// 合并 builtin、LobeHub Skill 和 Klavis
|
|
468
|
+
const allBuiltinItems = [
|
|
469
|
+
...enabledBuiltinItems,
|
|
470
|
+
...connectedKlavisItems,
|
|
471
|
+
...connectedLobehubSkillItems,
|
|
472
|
+
];
|
|
418
473
|
|
|
419
474
|
if (allBuiltinItems.length > 0) {
|
|
420
475
|
items.push({
|
|
@@ -462,6 +517,7 @@ const AgentTool = memo<AgentToolProps>(
|
|
|
462
517
|
}, [
|
|
463
518
|
filteredBuiltinList,
|
|
464
519
|
klavisServerItems,
|
|
520
|
+
lobehubSkillItems,
|
|
465
521
|
installedPluginList,
|
|
466
522
|
plugins,
|
|
467
523
|
isToolEnabled,
|
|
@@ -526,7 +582,7 @@ const AgentTool = memo<AgentToolProps>(
|
|
|
526
582
|
overflowY: 'visible',
|
|
527
583
|
},
|
|
528
584
|
}}
|
|
529
|
-
minHeight={isKlavisEnabledInEnv ? 500 : undefined}
|
|
585
|
+
minHeight={isKlavisEnabledInEnv || isLobehubSkillEnabled ? 500 : undefined}
|
|
530
586
|
minWidth={400}
|
|
531
587
|
placement={'bottomLeft'}
|
|
532
588
|
popupRender={(menu) => (
|
|
@@ -554,7 +610,7 @@ const AgentTool = memo<AgentToolProps>(
|
|
|
554
610
|
className={styles.scroller}
|
|
555
611
|
style={{
|
|
556
612
|
maxHeight: 500,
|
|
557
|
-
minHeight: isKlavisEnabledInEnv ? 500 : undefined,
|
|
613
|
+
minHeight: isKlavisEnabledInEnv || isLobehubSkillEnabled ? 500 : undefined,
|
|
558
614
|
}}
|
|
559
615
|
>
|
|
560
616
|
{menu}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
KLAVIS_SERVER_TYPES,
|
|
5
|
+
type KlavisServerType,
|
|
6
|
+
LOBEHUB_SKILL_PROVIDERS,
|
|
7
|
+
type LobehubSkillProviderType,
|
|
8
|
+
} from '@lobechat/const';
|
|
4
9
|
import { Avatar, Icon, Tag } from '@lobehub/ui';
|
|
5
10
|
import { createStaticStyles, cssVar } from 'antd-style';
|
|
6
11
|
import isEqual from 'fast-deep-equal';
|
|
@@ -16,6 +21,7 @@ import { useToolStore } from '@/store/tool';
|
|
|
16
21
|
import {
|
|
17
22
|
builtinToolSelectors,
|
|
18
23
|
klavisStoreSelectors,
|
|
24
|
+
lobehubSkillStoreSelectors,
|
|
19
25
|
pluginSelectors,
|
|
20
26
|
} from '@/store/tool/selectors';
|
|
21
27
|
import { type LobeToolMetaWithAvailability } from '@/store/tool/slices/builtin/selectors';
|
|
@@ -31,6 +37,19 @@ const KlavisIcon = memo<Pick<KlavisServerType, 'icon' | 'label'>>(({ icon, label
|
|
|
31
37
|
return <Icon fill={cssVar.colorText} icon={icon} size={16} />;
|
|
32
38
|
});
|
|
33
39
|
|
|
40
|
+
/**
|
|
41
|
+
* LobeHub Skill Provider 图标组件
|
|
42
|
+
*/
|
|
43
|
+
const LobehubSkillIcon = memo<Pick<LobehubSkillProviderType, 'icon' | 'label'>>(
|
|
44
|
+
({ icon, label }) => {
|
|
45
|
+
if (typeof icon === 'string') {
|
|
46
|
+
return <img alt={label} height={16} src={icon} style={{ flexShrink: 0 }} width={16} />;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return <Icon fill={cssVar.colorText} icon={icon} size={16} />;
|
|
50
|
+
},
|
|
51
|
+
);
|
|
52
|
+
|
|
34
53
|
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
35
54
|
notInstalledTag: css`
|
|
36
55
|
border-color: ${cssVar.colorWarningBorder};
|
|
@@ -80,10 +99,14 @@ const PluginTag = memo<PluginTagProps>(
|
|
|
80
99
|
const allKlavisServers = useToolStore(klavisStoreSelectors.getServers, isEqual);
|
|
81
100
|
const isKlavisEnabledInEnv = useServerConfigStore(serverConfigSelectors.enableKlavis);
|
|
82
101
|
|
|
102
|
+
// LobeHub Skill 相关状态
|
|
103
|
+
const allLobehubSkillServers = useToolStore(lobehubSkillStoreSelectors.getServers, isEqual);
|
|
104
|
+
const isLobehubSkillEnabled = useServerConfigStore(serverConfigSelectors.enableLobehubSkill);
|
|
105
|
+
|
|
83
106
|
// Check if plugin is installed
|
|
84
107
|
const isInstalled = useToolStore(pluginSelectors.isPluginInstalled(identifier));
|
|
85
108
|
|
|
86
|
-
// Try to find in local lists first (including Klavis)
|
|
109
|
+
// Try to find in local lists first (including Klavis and LobehubSkill)
|
|
87
110
|
const localMeta = useMemo(() => {
|
|
88
111
|
// Check if it's a Klavis server type
|
|
89
112
|
if (isKlavisEnabledInEnv) {
|
|
@@ -102,6 +125,23 @@ const PluginTag = memo<PluginTagProps>(
|
|
|
102
125
|
}
|
|
103
126
|
}
|
|
104
127
|
|
|
128
|
+
// Check if it's a LobeHub Skill provider
|
|
129
|
+
if (isLobehubSkillEnabled) {
|
|
130
|
+
const lobehubSkillProvider = LOBEHUB_SKILL_PROVIDERS.find((p) => p.id === identifier);
|
|
131
|
+
if (lobehubSkillProvider) {
|
|
132
|
+
// Check if this LobehubSkill provider is connected
|
|
133
|
+
const connectedServer = allLobehubSkillServers.find((s) => s.identifier === identifier);
|
|
134
|
+
return {
|
|
135
|
+
availableInWeb: true,
|
|
136
|
+
icon: lobehubSkillProvider.icon,
|
|
137
|
+
isInstalled: !!connectedServer,
|
|
138
|
+
label: lobehubSkillProvider.label,
|
|
139
|
+
title: lobehubSkillProvider.label,
|
|
140
|
+
type: 'lobehub-skill' as const,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
105
145
|
const builtinMeta = builtinList.find((p) => p.identifier === identifier);
|
|
106
146
|
if (builtinMeta) {
|
|
107
147
|
// availableInWeb is only present when using allMetaList
|
|
@@ -130,7 +170,15 @@ const PluginTag = memo<PluginTagProps>(
|
|
|
130
170
|
}
|
|
131
171
|
|
|
132
172
|
return null;
|
|
133
|
-
}, [
|
|
173
|
+
}, [
|
|
174
|
+
identifier,
|
|
175
|
+
builtinList,
|
|
176
|
+
installedPluginList,
|
|
177
|
+
isKlavisEnabledInEnv,
|
|
178
|
+
allKlavisServers,
|
|
179
|
+
isLobehubSkillEnabled,
|
|
180
|
+
allLobehubSkillServers,
|
|
181
|
+
]);
|
|
134
182
|
|
|
135
183
|
// Fetch from remote if not found locally
|
|
136
184
|
const usePluginDetail = useDiscoverStore((s) => s.usePluginDetail);
|
|
@@ -162,6 +210,11 @@ const PluginTag = memo<PluginTagProps>(
|
|
|
162
210
|
return <KlavisIcon icon={meta.icon} label={meta.label} />;
|
|
163
211
|
}
|
|
164
212
|
|
|
213
|
+
// LobeHub Skill type has icon property
|
|
214
|
+
if (meta.type === 'lobehub-skill' && 'icon' in meta && 'label' in meta) {
|
|
215
|
+
return <LobehubSkillIcon icon={meta.icon} label={meta.label} />;
|
|
216
|
+
}
|
|
217
|
+
|
|
165
218
|
// Builtin type has avatar
|
|
166
219
|
if (meta.type === 'builtin' && 'avatar' in meta && meta.avatar) {
|
|
167
220
|
return <Avatar avatar={meta.avatar} shape={'square'} size={16} style={{ flexShrink: 0 }} />;
|
|
@@ -278,6 +278,7 @@ export default {
|
|
|
278
278
|
'plugin.settings.title': '{{id}} Skill Configuration',
|
|
279
279
|
'plugin.settings.tooltip': 'Skill Configuration',
|
|
280
280
|
'plugin.store': 'Skill Store',
|
|
281
|
+
'publishToCommunity': 'Publish to Community',
|
|
281
282
|
'settingAgent.avatar.sizeExceeded': 'Image size exceeds 1MB limit, please choose a smaller image',
|
|
282
283
|
'settingAgent.avatar.title': 'Avatar',
|
|
283
284
|
'settingAgent.backgroundColor.title': 'Background Color',
|
|
@@ -62,6 +62,8 @@ export default {
|
|
|
62
62
|
'funds.packages.expiresIn': 'Expires in {{days}} days',
|
|
63
63
|
'funds.packages.expiresToday': 'Expires today',
|
|
64
64
|
'funds.packages.expiringSoon': 'Expiring soon',
|
|
65
|
+
'funds.packages.gift': 'Gift',
|
|
66
|
+
'funds.packages.giftedOn': 'Gifted on {{date}}',
|
|
65
67
|
'funds.packages.noPackages': 'No credit packages',
|
|
66
68
|
'funds.packages.purchaseFirst': 'Purchase your first credit package',
|
|
67
69
|
'funds.packages.purchasedOn': 'Purchased on {{date}}',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AgentBuilderIdentifier } from '@lobechat/builtin-tool-agent-builder';
|
|
2
|
-
import { KLAVIS_SERVER_TYPES } from '@lobechat/const';
|
|
2
|
+
import { KLAVIS_SERVER_TYPES, LOBEHUB_SKILL_PROVIDERS } from '@lobechat/const';
|
|
3
3
|
import type { OfficialToolItem } from '@lobechat/context-engine';
|
|
4
4
|
import {
|
|
5
5
|
type FetchSSEOptions,
|
|
@@ -41,6 +41,7 @@ import { getToolStoreState } from '@/store/tool';
|
|
|
41
41
|
import {
|
|
42
42
|
builtinToolSelectors,
|
|
43
43
|
klavisStoreSelectors,
|
|
44
|
+
lobehubSkillStoreSelectors,
|
|
44
45
|
pluginSelectors,
|
|
45
46
|
} from '@/store/tool/selectors';
|
|
46
47
|
import { getUserStoreState, useUserStore } from '@/store/user';
|
|
@@ -221,6 +222,28 @@ class ChatService {
|
|
|
221
222
|
}
|
|
222
223
|
}
|
|
223
224
|
|
|
225
|
+
// Get LobehubSkill providers (if enabled)
|
|
226
|
+
const isLobehubSkillEnabled =
|
|
227
|
+
typeof window !== 'undefined' &&
|
|
228
|
+
window.global_serverConfigStore?.getState()?.serverConfig?.enableLobehubSkill;
|
|
229
|
+
|
|
230
|
+
if (isLobehubSkillEnabled) {
|
|
231
|
+
const allLobehubSkillServers = lobehubSkillStoreSelectors.getServers(toolState);
|
|
232
|
+
|
|
233
|
+
for (const provider of LOBEHUB_SKILL_PROVIDERS) {
|
|
234
|
+
const server = allLobehubSkillServers.find((s) => s.identifier === provider.id);
|
|
235
|
+
|
|
236
|
+
officialTools.push({
|
|
237
|
+
description: `LobeHub Skill Provider: ${provider.label}`,
|
|
238
|
+
enabled: enabledPlugins.includes(provider.id),
|
|
239
|
+
identifier: provider.id,
|
|
240
|
+
installed: !!server,
|
|
241
|
+
name: provider.label,
|
|
242
|
+
type: 'lobehub-skill',
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
224
247
|
agentBuilderContext = {
|
|
225
248
|
...baseContext,
|
|
226
249
|
officialTools,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AgentBuilderIdentifier } from '@lobechat/builtin-tool-agent-builder';
|
|
2
2
|
import { GroupAgentBuilderIdentifier } from '@lobechat/builtin-tool-group-agent-builder';
|
|
3
3
|
import { GTDIdentifier } from '@lobechat/builtin-tool-gtd';
|
|
4
|
-
import { KLAVIS_SERVER_TYPES, isDesktop } from '@lobechat/const';
|
|
4
|
+
import { KLAVIS_SERVER_TYPES, LOBEHUB_SKILL_PROVIDERS, isDesktop } from '@lobechat/const';
|
|
5
5
|
import {
|
|
6
6
|
type AgentBuilderContext,
|
|
7
7
|
type AgentGroupConfig,
|
|
@@ -29,7 +29,11 @@ import { getChatGroupStoreState } from '@/store/agentGroup';
|
|
|
29
29
|
import { agentGroupSelectors } from '@/store/agentGroup/selectors';
|
|
30
30
|
import { getChatStoreState } from '@/store/chat';
|
|
31
31
|
import { getToolStoreState } from '@/store/tool';
|
|
32
|
-
import {
|
|
32
|
+
import {
|
|
33
|
+
builtinToolSelectors,
|
|
34
|
+
klavisStoreSelectors,
|
|
35
|
+
lobehubSkillStoreSelectors,
|
|
36
|
+
} from '@/store/tool/selectors';
|
|
33
37
|
|
|
34
38
|
import { isCanUseVideo, isCanUseVision } from '../helper';
|
|
35
39
|
import {
|
|
@@ -217,6 +221,28 @@ export const contextEngineering = async ({
|
|
|
217
221
|
}
|
|
218
222
|
}
|
|
219
223
|
|
|
224
|
+
// Get LobehubSkill providers (if enabled)
|
|
225
|
+
const isLobehubSkillEnabled =
|
|
226
|
+
typeof window !== 'undefined' &&
|
|
227
|
+
window.global_serverConfigStore?.getState()?.serverConfig?.enableLobehubSkill;
|
|
228
|
+
|
|
229
|
+
if (isLobehubSkillEnabled) {
|
|
230
|
+
const allLobehubSkillServers = lobehubSkillStoreSelectors.getServers(toolState);
|
|
231
|
+
|
|
232
|
+
for (const provider of LOBEHUB_SKILL_PROVIDERS) {
|
|
233
|
+
const server = allLobehubSkillServers.find((s) => s.identifier === provider.id);
|
|
234
|
+
|
|
235
|
+
officialTools.push({
|
|
236
|
+
description: `LobeHub Skill Provider: ${provider.label}`,
|
|
237
|
+
enabled: enabledPlugins.includes(provider.id),
|
|
238
|
+
identifier: provider.id,
|
|
239
|
+
installed: !!server,
|
|
240
|
+
name: provider.label,
|
|
241
|
+
type: 'lobehub-skill',
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
220
246
|
groupAgentBuilderContext = {
|
|
221
247
|
config: {
|
|
222
248
|
openingMessage: activeGroupDetail.config?.openingMessage || undefined,
|
|
@@ -123,10 +123,20 @@ export const pluginTypes: StateCreator<
|
|
|
123
123
|
const context = operationId ? { operationId } : undefined;
|
|
124
124
|
|
|
125
125
|
// Get agent ID, group ID, and topic ID from operation context
|
|
126
|
-
|
|
126
|
+
let agentId = operation?.context?.agentId;
|
|
127
127
|
let groupId = operation?.context?.groupId;
|
|
128
128
|
const topicId = operation?.context?.topicId;
|
|
129
129
|
|
|
130
|
+
// For agent-builder tools, inject activeAgentId from store if not in context
|
|
131
|
+
// This is needed because AgentBuilderProvider uses a separate scope for messages
|
|
132
|
+
// but the tools need the correct agentId for execution
|
|
133
|
+
if (payload.identifier === 'lobe-agent-builder') {
|
|
134
|
+
const activeAgentId = get().activeAgentId;
|
|
135
|
+
if (activeAgentId) {
|
|
136
|
+
agentId = activeAgentId;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
130
140
|
// For group-agent-builder tools, inject activeGroupId from store if not in context
|
|
131
141
|
// This is needed because AgentBuilderProvider uses a separate scope for messages
|
|
132
142
|
// but still needs groupId for tool execution
|
|
@@ -84,6 +84,31 @@ describe('SettingsAction', () => {
|
|
|
84
84
|
expect.any(AbortSignal),
|
|
85
85
|
);
|
|
86
86
|
});
|
|
87
|
+
|
|
88
|
+
it('should include field in diffs when user resets it to default value', async () => {
|
|
89
|
+
const { result } = renderHook(() => useUserStore());
|
|
90
|
+
|
|
91
|
+
// First, set memory.enabled to false (non-default value)
|
|
92
|
+
await act(async () => {
|
|
93
|
+
await result.current.setSettings({ memory: { enabled: false } });
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
expect(userService.updateUserSettings).toHaveBeenLastCalledWith(
|
|
97
|
+
expect.objectContaining({ memory: { enabled: false } }),
|
|
98
|
+
expect.any(AbortSignal),
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
// Then, reset memory.enabled back to true (default value)
|
|
102
|
+
// This should still include memory in the diffs to override the previously saved value
|
|
103
|
+
await act(async () => {
|
|
104
|
+
await result.current.setSettings({ memory: { enabled: true } });
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
expect(userService.updateUserSettings).toHaveBeenLastCalledWith(
|
|
108
|
+
expect.objectContaining({ memory: { enabled: true } }),
|
|
109
|
+
expect.any(AbortSignal),
|
|
110
|
+
);
|
|
111
|
+
});
|
|
87
112
|
});
|
|
88
113
|
|
|
89
114
|
describe('updateDefaultAgent', () => {
|
|
@@ -103,6 +103,17 @@ export const createSettingsSlice: StateCreator<
|
|
|
103
103
|
if (isEqual(prevSetting, nextSettings)) return;
|
|
104
104
|
|
|
105
105
|
const diffs = difference(nextSettings, defaultSettings);
|
|
106
|
+
|
|
107
|
+
// When user resets a field to default value, we need to explicitly include it in diffs
|
|
108
|
+
// to override the previously saved non-default value in the backend
|
|
109
|
+
const changedFields = difference(nextSettings, prevSetting);
|
|
110
|
+
for (const key of Object.keys(changedFields)) {
|
|
111
|
+
// Only handle fields that were previously set by user (exist in prevSetting)
|
|
112
|
+
if (key in prevSetting && !(key in diffs)) {
|
|
113
|
+
(diffs as any)[key] = (nextSettings as any)[key];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
106
117
|
set({ settings: diffs }, false, 'optimistic_updateSettings');
|
|
107
118
|
|
|
108
119
|
const abortController = get().internal_createSignal();
|