@lobehub/lobehub 2.0.0-next.335 → 2.0.0-next.336
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 +33 -0
- package/changelog/v1.json +12 -0
- package/package.json +1 -1
- package/packages/builtin-tool-group-management/src/manifest.ts +54 -53
- package/packages/builtin-tool-group-management/src/systemRole.ts +43 -111
- package/packages/context-engine/src/engine/tools/ToolArgumentsRepairer.ts +129 -0
- package/packages/context-engine/src/engine/tools/__tests__/ToolArgumentsRepairer.test.ts +186 -0
- package/packages/context-engine/src/engine/tools/index.ts +3 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/tasks/index.ts +2 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/tasks/with-assistant-group.json +156 -0
- package/packages/conversation-flow/src/__tests__/parse.test.ts +22 -0
- package/packages/conversation-flow/src/transformation/FlatListBuilder.ts +88 -11
- package/packages/types/src/openai/chat.ts +0 -4
- package/src/app/[variants]/(main)/community/(detail)/user/features/DetailProvider.tsx +5 -1
- package/src/app/[variants]/(main)/community/(detail)/user/features/UserAgentCard.tsx +8 -8
- package/src/app/[variants]/(main)/community/(detail)/user/features/UserGroupCard.tsx +142 -15
- package/src/app/[variants]/(main)/community/(detail)/user/features/useUserDetail.ts +45 -20
- package/src/server/routers/lambda/market/agentGroup.ts +179 -1
- package/src/server/services/discover/index.ts +4 -0
- package/src/services/chat/chat.test.ts +109 -104
- package/src/services/chat/index.ts +13 -32
- package/src/services/chat/mecha/agentConfigResolver.test.ts +113 -0
- package/src/services/chat/mecha/agentConfigResolver.ts +15 -5
- package/src/services/marketApi.ts +14 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/helpers/testExecutor.ts +13 -0
- package/src/store/chat/agents/createAgentExecutors.ts +13 -1
- package/src/store/chat/slices/aiChat/actions/__tests__/conversationControl.test.ts +5 -1
- package/src/store/chat/slices/aiChat/actions/__tests__/fixtures.ts +14 -0
- package/src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts +131 -7
- package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +61 -62
- package/src/store/chat/slices/plugin/action.test.ts +71 -0
- package/src/store/chat/slices/plugin/actions/internals.ts +14 -5
|
@@ -1,8 +1,28 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import {
|
|
4
|
+
Tag as AntTag,
|
|
5
|
+
Avatar,
|
|
6
|
+
Block,
|
|
7
|
+
DropdownMenu,
|
|
8
|
+
Flexbox,
|
|
9
|
+
Icon,
|
|
10
|
+
Tag,
|
|
11
|
+
Text,
|
|
12
|
+
Tooltip,
|
|
13
|
+
TooltipGroup,
|
|
14
|
+
} from '@lobehub/ui';
|
|
15
|
+
import { createStaticStyles, cx } from 'antd-style';
|
|
16
|
+
import {
|
|
17
|
+
AlertTriangle,
|
|
18
|
+
ClockIcon,
|
|
19
|
+
DownloadIcon,
|
|
20
|
+
Eye,
|
|
21
|
+
EyeOff,
|
|
22
|
+
MoreVerticalIcon,
|
|
23
|
+
Pencil,
|
|
24
|
+
UsersIcon,
|
|
25
|
+
} from 'lucide-react';
|
|
6
26
|
import qs from 'query-string';
|
|
7
27
|
import { memo, useCallback } from 'react';
|
|
8
28
|
import { useTranslation } from 'react-i18next';
|
|
@@ -10,9 +30,31 @@ import { Link, useNavigate } from 'react-router-dom';
|
|
|
10
30
|
import urlJoin from 'url-join';
|
|
11
31
|
|
|
12
32
|
import PublishedTime from '@/components/PublishedTime';
|
|
13
|
-
import { type DiscoverGroupAgentItem } from '@/types/discover';
|
|
33
|
+
import { type DiscoverGroupAgentItem, type GroupAgentStatus } from '@/types/discover';
|
|
14
34
|
import { formatIntergerNumber } from '@/utils/format';
|
|
15
35
|
|
|
36
|
+
import { useUserDetailContext } from './DetailProvider';
|
|
37
|
+
|
|
38
|
+
const getStatusTagColor = (status?: GroupAgentStatus) => {
|
|
39
|
+
switch (status) {
|
|
40
|
+
case 'published': {
|
|
41
|
+
return 'green';
|
|
42
|
+
}
|
|
43
|
+
case 'unpublished': {
|
|
44
|
+
return 'orange';
|
|
45
|
+
}
|
|
46
|
+
case 'deprecated': {
|
|
47
|
+
return 'red';
|
|
48
|
+
}
|
|
49
|
+
case 'archived': {
|
|
50
|
+
return 'default';
|
|
51
|
+
}
|
|
52
|
+
default: {
|
|
53
|
+
return 'default';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
16
58
|
const styles = createStaticStyles(({ css, cssVar }) => {
|
|
17
59
|
return {
|
|
18
60
|
desc: css`
|
|
@@ -25,6 +67,16 @@ const styles = createStaticStyles(({ css, cssVar }) => {
|
|
|
25
67
|
border-block-start: 1px dashed ${cssVar.colorBorder};
|
|
26
68
|
background: ${cssVar.colorBgContainer};
|
|
27
69
|
`,
|
|
70
|
+
moreButton: css`
|
|
71
|
+
position: absolute;
|
|
72
|
+
z-index: 10;
|
|
73
|
+
inset-block-start: 12px;
|
|
74
|
+
inset-inline-end: 12px;
|
|
75
|
+
|
|
76
|
+
opacity: 0;
|
|
77
|
+
|
|
78
|
+
transition: opacity 0.2s;
|
|
79
|
+
`,
|
|
28
80
|
secondaryDesc: css`
|
|
29
81
|
font-size: 12px;
|
|
30
82
|
color: ${cssVar.colorTextDescription};
|
|
@@ -47,15 +99,31 @@ const styles = createStaticStyles(({ css, cssVar }) => {
|
|
|
47
99
|
color: ${cssVar.colorLink};
|
|
48
100
|
}
|
|
49
101
|
`,
|
|
102
|
+
wrapper: css`
|
|
103
|
+
&:hover .more-button {
|
|
104
|
+
opacity: 1;
|
|
105
|
+
}
|
|
106
|
+
`,
|
|
50
107
|
};
|
|
51
108
|
});
|
|
52
109
|
|
|
53
110
|
type UserGroupCardProps = DiscoverGroupAgentItem;
|
|
54
111
|
|
|
55
112
|
const UserGroupCard = memo<UserGroupCardProps>(
|
|
56
|
-
({
|
|
57
|
-
|
|
113
|
+
({
|
|
114
|
+
avatar,
|
|
115
|
+
title,
|
|
116
|
+
description,
|
|
117
|
+
createdAt,
|
|
118
|
+
category,
|
|
119
|
+
installCount,
|
|
120
|
+
identifier,
|
|
121
|
+
memberCount,
|
|
122
|
+
status,
|
|
123
|
+
}) => {
|
|
124
|
+
const { t } = useTranslation(['discover', 'setting']);
|
|
58
125
|
const navigate = useNavigate();
|
|
126
|
+
const { isOwner, onStatusChange } = useUserDetailContext();
|
|
59
127
|
|
|
60
128
|
const link = qs.stringifyUrl(
|
|
61
129
|
{
|
|
@@ -65,12 +133,55 @@ const UserGroupCard = memo<UserGroupCardProps>(
|
|
|
65
133
|
{ skipNull: true },
|
|
66
134
|
);
|
|
67
135
|
|
|
136
|
+
const isPublished = status === 'published';
|
|
137
|
+
|
|
68
138
|
const handleCardClick = useCallback(() => {
|
|
69
139
|
navigate(link);
|
|
70
140
|
}, [link, navigate]);
|
|
71
141
|
|
|
142
|
+
const handleEdit = useCallback(() => {
|
|
143
|
+
navigate(urlJoin('/group', identifier, 'profile'));
|
|
144
|
+
}, [identifier, navigate]);
|
|
145
|
+
|
|
146
|
+
const handleStatusAction = useCallback(
|
|
147
|
+
(action: 'publish' | 'unpublish' | 'deprecate') => {
|
|
148
|
+
onStatusChange?.(identifier, action, 'group');
|
|
149
|
+
},
|
|
150
|
+
[identifier, onStatusChange],
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
const menuItems = isOwner
|
|
154
|
+
? [
|
|
155
|
+
{
|
|
156
|
+
icon: <Icon icon={Pencil} />,
|
|
157
|
+
key: 'edit',
|
|
158
|
+
label: t('setting:myAgents.actions.edit'),
|
|
159
|
+
onClick: handleEdit,
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
type: 'divider' as const,
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
icon: <Icon icon={isPublished ? EyeOff : Eye} />,
|
|
166
|
+
key: 'togglePublish',
|
|
167
|
+
label: isPublished
|
|
168
|
+
? t('setting:myAgents.actions.unpublish')
|
|
169
|
+
: t('setting:myAgents.actions.publish'),
|
|
170
|
+
onClick: () => handleStatusAction(isPublished ? 'unpublish' : 'publish'),
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
danger: true,
|
|
174
|
+
icon: <Icon icon={AlertTriangle} />,
|
|
175
|
+
key: 'deprecate',
|
|
176
|
+
label: t('setting:myAgents.actions.deprecate'),
|
|
177
|
+
onClick: () => handleStatusAction('deprecate'),
|
|
178
|
+
},
|
|
179
|
+
]
|
|
180
|
+
: [];
|
|
181
|
+
|
|
72
182
|
return (
|
|
73
183
|
<Block
|
|
184
|
+
className={styles.wrapper}
|
|
74
185
|
clickable
|
|
75
186
|
height={'100%'}
|
|
76
187
|
onClick={handleCardClick}
|
|
@@ -82,6 +193,15 @@ const UserGroupCard = memo<UserGroupCardProps>(
|
|
|
82
193
|
variant={'outlined'}
|
|
83
194
|
width={'100%'}
|
|
84
195
|
>
|
|
196
|
+
{isOwner && (
|
|
197
|
+
<div onClick={(e) => e.stopPropagation()}>
|
|
198
|
+
<DropdownMenu items={menuItems as any}>
|
|
199
|
+
<div className={cx('more-button', styles.moreButton)}>
|
|
200
|
+
<Icon icon={MoreVerticalIcon} size={16} style={{ cursor: 'pointer' }} />
|
|
201
|
+
</div>
|
|
202
|
+
</DropdownMenu>
|
|
203
|
+
</div>
|
|
204
|
+
)}
|
|
85
205
|
<Flexbox
|
|
86
206
|
align={'flex-start'}
|
|
87
207
|
gap={16}
|
|
@@ -105,15 +225,22 @@ const UserGroupCard = memo<UserGroupCardProps>(
|
|
|
105
225
|
overflow: 'hidden',
|
|
106
226
|
}}
|
|
107
227
|
>
|
|
108
|
-
<
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
{title}
|
|
115
|
-
|
|
116
|
-
|
|
228
|
+
<Flexbox align={'center'} gap={8} horizontal>
|
|
229
|
+
<Link
|
|
230
|
+
onClick={(e) => e.stopPropagation()}
|
|
231
|
+
style={{ color: 'inherit', flex: 1, overflow: 'hidden' }}
|
|
232
|
+
to={link}
|
|
233
|
+
>
|
|
234
|
+
<Text as={'h3'} className={styles.title} ellipsis style={{ flex: 1 }}>
|
|
235
|
+
{title}
|
|
236
|
+
</Text>
|
|
237
|
+
</Link>
|
|
238
|
+
{isOwner && status && (
|
|
239
|
+
<AntTag color={getStatusTagColor(status)} style={{ flexShrink: 0, margin: 0 }}>
|
|
240
|
+
{t(`setting:myAgents.status.${status}`)}
|
|
241
|
+
</AntTag>
|
|
242
|
+
)}
|
|
243
|
+
</Flexbox>
|
|
117
244
|
</Flexbox>
|
|
118
245
|
</Flexbox>
|
|
119
246
|
</Flexbox>
|
|
@@ -6,8 +6,10 @@ import { useTranslation } from 'react-i18next';
|
|
|
6
6
|
|
|
7
7
|
import { useMarketAuth } from '@/layout/AuthProvider/MarketAuth';
|
|
8
8
|
import { marketApiService } from '@/services/marketApi';
|
|
9
|
+
import { serverConfigSelectors, useServerConfigStore } from '@/store/serverConfig';
|
|
9
10
|
|
|
10
11
|
export type AgentStatusAction = 'publish' | 'unpublish' | 'deprecate';
|
|
12
|
+
export type EntityType = 'agent' | 'group';
|
|
11
13
|
|
|
12
14
|
interface UseUserDetailOptions {
|
|
13
15
|
onMutate?: () => void;
|
|
@@ -17,43 +19,67 @@ export const useUserDetail = ({ onMutate }: UseUserDetailOptions = {}) => {
|
|
|
17
19
|
const { t } = useTranslation('setting');
|
|
18
20
|
const { message, modal } = App.useApp();
|
|
19
21
|
const { session } = useMarketAuth();
|
|
22
|
+
const enableMarketTrustedClient = useServerConfigStore(
|
|
23
|
+
serverConfigSelectors.enableMarketTrustedClient,
|
|
24
|
+
);
|
|
20
25
|
|
|
21
26
|
const handleStatusChange = useCallback(
|
|
22
|
-
async (identifier: string, action: AgentStatusAction) => {
|
|
23
|
-
if (!session?.accessToken) {
|
|
27
|
+
async (identifier: string, action: AgentStatusAction, type: EntityType = 'agent') => {
|
|
28
|
+
if (!enableMarketTrustedClient && !session?.accessToken) {
|
|
24
29
|
message.error(t('myAgents.errors.notAuthenticated'));
|
|
25
30
|
return;
|
|
26
31
|
}
|
|
27
32
|
|
|
28
|
-
const messageKey =
|
|
33
|
+
const messageKey = `${type}-status-${action}`;
|
|
29
34
|
const loadingText = t(`myAgents.actions.${action}Loading` as any);
|
|
30
35
|
const successText = t(`myAgents.actions.${action}Success` as any);
|
|
31
36
|
const errorText = t(`myAgents.actions.${action}Error` as any);
|
|
32
37
|
|
|
33
|
-
async function executeStatusChange(
|
|
38
|
+
async function executeStatusChange(
|
|
39
|
+
identifier: string,
|
|
40
|
+
action: AgentStatusAction,
|
|
41
|
+
type: EntityType,
|
|
42
|
+
) {
|
|
34
43
|
try {
|
|
35
44
|
message.loading({ content: loadingText, key: messageKey });
|
|
36
45
|
marketApiService.setAccessToken(session!.accessToken);
|
|
37
46
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
if (type === 'group') {
|
|
48
|
+
switch (action) {
|
|
49
|
+
case 'publish': {
|
|
50
|
+
await marketApiService.publishAgentGroup(identifier);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
case 'unpublish': {
|
|
54
|
+
await marketApiService.unpublishAgentGroup(identifier);
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
case 'deprecate': {
|
|
58
|
+
await marketApiService.deprecateAgentGroup(identifier);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
46
61
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
62
|
+
} else {
|
|
63
|
+
switch (action) {
|
|
64
|
+
case 'publish': {
|
|
65
|
+
await marketApiService.publishAgent(identifier);
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
case 'unpublish': {
|
|
69
|
+
await marketApiService.unpublishAgent(identifier);
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
case 'deprecate': {
|
|
73
|
+
await marketApiService.deprecateAgent(identifier);
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
50
76
|
}
|
|
51
77
|
}
|
|
52
78
|
|
|
53
79
|
message.success({ content: successText, key: messageKey });
|
|
54
80
|
onMutate?.();
|
|
55
81
|
} catch (error) {
|
|
56
|
-
console.error(`[useUserDetail] ${action}
|
|
82
|
+
console.error(`[useUserDetail] ${action} ${type} error:`, error);
|
|
57
83
|
message.error({
|
|
58
84
|
content: `${errorText}: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
59
85
|
key: messageKey,
|
|
@@ -61,7 +87,6 @@ export const useUserDetail = ({ onMutate }: UseUserDetailOptions = {}) => {
|
|
|
61
87
|
}
|
|
62
88
|
}
|
|
63
89
|
|
|
64
|
-
// For deprecate action, show confirmation dialog first
|
|
65
90
|
if (action === 'deprecate') {
|
|
66
91
|
modal.confirm({
|
|
67
92
|
cancelText: t('myAgents.actions.cancel'),
|
|
@@ -69,16 +94,16 @@ export const useUserDetail = ({ onMutate }: UseUserDetailOptions = {}) => {
|
|
|
69
94
|
okButtonProps: { danger: true },
|
|
70
95
|
okText: t('myAgents.actions.confirmDeprecate'),
|
|
71
96
|
onOk: async () => {
|
|
72
|
-
await executeStatusChange(identifier, action);
|
|
97
|
+
await executeStatusChange(identifier, action, type);
|
|
73
98
|
},
|
|
74
99
|
title: t('myAgents.actions.deprecateConfirmTitle'),
|
|
75
100
|
});
|
|
76
101
|
return;
|
|
77
102
|
}
|
|
78
103
|
|
|
79
|
-
await executeStatusChange(identifier, action);
|
|
104
|
+
await executeStatusChange(identifier, action, type);
|
|
80
105
|
},
|
|
81
|
-
[session?.accessToken, message, modal, t, onMutate],
|
|
106
|
+
[enableMarketTrustedClient, session?.accessToken, message, modal, t, onMutate],
|
|
82
107
|
);
|
|
83
108
|
|
|
84
109
|
return {
|
|
@@ -202,6 +202,66 @@ export const agentGroupRouter = router({
|
|
|
202
202
|
|
|
203
203
|
|
|
204
204
|
/**
|
|
205
|
+
* Deprecate agent group
|
|
206
|
+
* POST /market/agent-group/:identifier/deprecate
|
|
207
|
+
*/
|
|
208
|
+
deprecateAgentGroup: agentGroupProcedure
|
|
209
|
+
.input(z.object({ identifier: z.string() }))
|
|
210
|
+
.mutation(async ({ input, ctx }) => {
|
|
211
|
+
log('deprecateAgentGroup input: %O', input);
|
|
212
|
+
|
|
213
|
+
try {
|
|
214
|
+
const deprecateUrl = `${MARKET_BASE_URL}/api/v1/agent-groups/${input.identifier}/deprecate`;
|
|
215
|
+
|
|
216
|
+
const headers: Record<string, string> = {
|
|
217
|
+
'Content-Type': 'application/json',
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
const userInfo = ctx.marketUserInfo as TrustedClientUserInfo | undefined;
|
|
221
|
+
const accessToken = (ctx as { marketOidcAccessToken?: string }).marketOidcAccessToken;
|
|
222
|
+
|
|
223
|
+
if (userInfo) {
|
|
224
|
+
const trustedClientToken = generateTrustedClientToken(userInfo);
|
|
225
|
+
if (trustedClientToken) {
|
|
226
|
+
headers['x-lobe-trust-token'] = trustedClientToken;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (!headers['x-lobe-trust-token'] && accessToken) {
|
|
231
|
+
headers['Authorization'] = `Bearer ${accessToken}`;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const response = await fetch(deprecateUrl, {
|
|
235
|
+
headers,
|
|
236
|
+
method: 'POST',
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
if (!response.ok) {
|
|
240
|
+
const errorText = await response.text();
|
|
241
|
+
log(
|
|
242
|
+
'Deprecate agent group failed: %s %s - %s',
|
|
243
|
+
response.status,
|
|
244
|
+
response.statusText,
|
|
245
|
+
errorText,
|
|
246
|
+
);
|
|
247
|
+
throw new Error(`Failed to deprecate agent group: ${response.statusText}`);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
log('Deprecate agent group success');
|
|
251
|
+
return { success: true };
|
|
252
|
+
} catch (error) {
|
|
253
|
+
log('Error deprecating agent group: %O', error);
|
|
254
|
+
throw new TRPCError({
|
|
255
|
+
cause: error,
|
|
256
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
257
|
+
message: error instanceof Error ? error.message : 'Failed to deprecate agent group',
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}),
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
/**
|
|
205
265
|
* Fork an agent group
|
|
206
266
|
* POST /market/agent-group/:identifier/fork
|
|
207
267
|
*/
|
|
@@ -340,7 +400,6 @@ getAgentGroupForkSource: agentGroupProcedure
|
|
|
340
400
|
|
|
341
401
|
|
|
342
402
|
|
|
343
|
-
|
|
344
403
|
/**
|
|
345
404
|
* Get all forks of an agent group
|
|
346
405
|
* GET /market/agent-group/:identifier/forks
|
|
@@ -401,6 +460,66 @@ getAgentGroupForks: agentGroupProcedure
|
|
|
401
460
|
|
|
402
461
|
|
|
403
462
|
|
|
463
|
+
/**
|
|
464
|
+
* Publish agent group
|
|
465
|
+
* POST /market/agent-group/:identifier/publish
|
|
466
|
+
*/
|
|
467
|
+
publishAgentGroup: agentGroupProcedure
|
|
468
|
+
.input(z.object({ identifier: z.string() }))
|
|
469
|
+
.mutation(async ({ input, ctx }) => {
|
|
470
|
+
log('publishAgentGroup input: %O', input);
|
|
471
|
+
|
|
472
|
+
try {
|
|
473
|
+
const publishUrl = `${MARKET_BASE_URL}/api/v1/agent-groups/${input.identifier}/publish`;
|
|
474
|
+
|
|
475
|
+
const headers: Record<string, string> = {
|
|
476
|
+
'Content-Type': 'application/json',
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
const userInfo = ctx.marketUserInfo as TrustedClientUserInfo | undefined;
|
|
480
|
+
const accessToken = (ctx as { marketOidcAccessToken?: string }).marketOidcAccessToken;
|
|
481
|
+
|
|
482
|
+
if (userInfo) {
|
|
483
|
+
const trustedClientToken = generateTrustedClientToken(userInfo);
|
|
484
|
+
if (trustedClientToken) {
|
|
485
|
+
headers['x-lobe-trust-token'] = trustedClientToken;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
if (!headers['x-lobe-trust-token'] && accessToken) {
|
|
490
|
+
headers['Authorization'] = `Bearer ${accessToken}`;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
const response = await fetch(publishUrl, {
|
|
494
|
+
headers,
|
|
495
|
+
method: 'POST',
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
if (!response.ok) {
|
|
499
|
+
const errorText = await response.text();
|
|
500
|
+
log(
|
|
501
|
+
'Publish agent group failed: %s %s - %s',
|
|
502
|
+
response.status,
|
|
503
|
+
response.statusText,
|
|
504
|
+
errorText,
|
|
505
|
+
);
|
|
506
|
+
throw new Error(`Failed to publish agent group: ${response.statusText}`);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
log('Publish agent group success');
|
|
510
|
+
return { success: true };
|
|
511
|
+
} catch (error) {
|
|
512
|
+
log('Error publishing agent group: %O', error);
|
|
513
|
+
throw new TRPCError({
|
|
514
|
+
cause: error,
|
|
515
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
516
|
+
message: error instanceof Error ? error.message : 'Failed to publish agent group',
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
}),
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
|
|
404
523
|
/**
|
|
405
524
|
* Unified publish or create agent group flow
|
|
406
525
|
* 1. Check if identifier exists and if current user is owner
|
|
@@ -494,6 +613,65 @@ publishOrCreate: agentGroupProcedure
|
|
|
494
613
|
});
|
|
495
614
|
}
|
|
496
615
|
}),
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Unpublish agent group
|
|
620
|
+
* POST /market/agent-group/:identifier/unpublish
|
|
621
|
+
*/
|
|
622
|
+
unpublishAgentGroup: agentGroupProcedure
|
|
623
|
+
.input(z.object({ identifier: z.string() }))
|
|
624
|
+
.mutation(async ({ input, ctx }) => {
|
|
625
|
+
log('unpublishAgentGroup input: %O', input);
|
|
626
|
+
|
|
627
|
+
try {
|
|
628
|
+
const unpublishUrl = `${MARKET_BASE_URL}/api/v1/agent-groups/${input.identifier}/unpublish`;
|
|
629
|
+
|
|
630
|
+
const headers: Record<string, string> = {
|
|
631
|
+
'Content-Type': 'application/json',
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
const userInfo = ctx.marketUserInfo as TrustedClientUserInfo | undefined;
|
|
635
|
+
const accessToken = (ctx as { marketOidcAccessToken?: string }).marketOidcAccessToken;
|
|
636
|
+
|
|
637
|
+
if (userInfo) {
|
|
638
|
+
const trustedClientToken = generateTrustedClientToken(userInfo);
|
|
639
|
+
if (trustedClientToken) {
|
|
640
|
+
headers['x-lobe-trust-token'] = trustedClientToken;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
if (!headers['x-lobe-trust-token'] && accessToken) {
|
|
645
|
+
headers['Authorization'] = `Bearer ${accessToken}`;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
const response = await fetch(unpublishUrl, {
|
|
649
|
+
headers,
|
|
650
|
+
method: 'POST',
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
if (!response.ok) {
|
|
654
|
+
const errorText = await response.text();
|
|
655
|
+
log(
|
|
656
|
+
'Unpublish agent group failed: %s %s - %s',
|
|
657
|
+
response.status,
|
|
658
|
+
response.statusText,
|
|
659
|
+
errorText,
|
|
660
|
+
);
|
|
661
|
+
throw new Error(`Failed to unpublish agent group: ${response.statusText}`);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
log('Unpublish agent group success');
|
|
665
|
+
return { success: true };
|
|
666
|
+
} catch (error) {
|
|
667
|
+
log('Error unpublishing agent group: %O', error);
|
|
668
|
+
throw new TRPCError({
|
|
669
|
+
cause: error,
|
|
670
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
671
|
+
message: error instanceof Error ? error.message : 'Failed to unpublish agent group',
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
}),
|
|
497
675
|
});
|
|
498
676
|
|
|
499
677
|
export type AgentGroupRouter = typeof agentGroupRouter;
|
|
@@ -1761,6 +1761,7 @@ export class DiscoverService {
|
|
|
1761
1761
|
knowledgeCount: agent.knowledgeCount || 0,
|
|
1762
1762
|
pluginCount: agent.pluginCount || 0,
|
|
1763
1763
|
schemaVersion: 1,
|
|
1764
|
+
status: agent.status,
|
|
1764
1765
|
tags: agent.tags || [],
|
|
1765
1766
|
title: agent.name || agent.identifier,
|
|
1766
1767
|
tokenUsage: agent.tokenUsage || 0,
|
|
@@ -1780,6 +1781,7 @@ export class DiscoverService {
|
|
|
1780
1781
|
isOfficial: group.isOfficial || false,
|
|
1781
1782
|
memberCount: 0, // Will be populated from memberAgents in detail view
|
|
1782
1783
|
schemaVersion: 1,
|
|
1784
|
+
status: group.status,
|
|
1783
1785
|
tags: group.tags || [],
|
|
1784
1786
|
title: group.name || group.identifier,
|
|
1785
1787
|
updatedAt: group.updatedAt,
|
|
@@ -1802,6 +1804,7 @@ export class DiscoverService {
|
|
|
1802
1804
|
knowledgeCount: agent.knowledgeCount || 0,
|
|
1803
1805
|
pluginCount: agent.pluginCount || 0,
|
|
1804
1806
|
schemaVersion: 1,
|
|
1807
|
+
status: agent.status,
|
|
1805
1808
|
tags: agent.tags || [],
|
|
1806
1809
|
title: agent.name || agent.identifier,
|
|
1807
1810
|
tokenUsage: agent.tokenUsage || 0,
|
|
@@ -1824,6 +1827,7 @@ export class DiscoverService {
|
|
|
1824
1827
|
isOfficial: group.isOfficial || false,
|
|
1825
1828
|
memberCount: 0, // Will be populated from memberAgents in detail view
|
|
1826
1829
|
schemaVersion: 1,
|
|
1830
|
+
status: group.status,
|
|
1827
1831
|
tags: group.tags || [],
|
|
1828
1832
|
title: group.name || group.identifier,
|
|
1829
1833
|
updatedAt: group.updatedAt,
|