🐛 fix: group publish to market should set local group market identifer (#11965)

* fix: when use group in market the supervisor plugins lost

* fix: slove the group pubilsh but not set the market id into group
This commit is contained in:
Shinji-Li
2026-01-29 22:30:14 +08:00
committed by GitHub
parent 7abc5142e0
commit 0bda4d9845
7 changed files with 51 additions and 85 deletions

View File

@@ -17,9 +17,11 @@ import { LobeChatDatabase } from '../../type';
export interface SupervisorAgentConfig {
avatar?: string;
backgroundColor?: string;
chatConfig?: any;
description?: string;
model?: string;
params?: any;
plugins?: string[];
provider?: string;
systemRole?: string;
tags?: string[];
@@ -172,9 +174,11 @@ export class AgentGroupRepository {
.values({
avatar: supervisorConfig?.avatar,
backgroundColor: supervisorConfig?.backgroundColor,
chatConfig: supervisorConfig?.chatConfig,
description: supervisorConfig?.description,
model: supervisorConfig?.model,
params: supervisorConfig?.params,
plugins: supervisorConfig?.plugins,
provider: supervisorConfig?.provider,
systemRole: supervisorConfig?.systemRole,
tags: supervisorConfig?.tags,

View File

@@ -134,7 +134,8 @@ const ForkGroupAndChat = memo<{ mobile?: boolean }>(() => {
// Group content is the supervisor's systemRole (for backward compatibility)
content: config.systemRole || supervisorConfig?.systemRole,
...meta,
marketIdentifier: forkResult.group.identifier, // Store the new market identifier
// Store marketIdentifier at top-level (same as agents)
marketIdentifier: forkResult.group.identifier,
};
// Step 5: Prepare member agents from market data

View File

@@ -28,8 +28,8 @@ const GroupPublishButton = memo(() => {
// Determine action based on whether we have an existing marketIdentifier
// Backend will verify ownership and decide to create new or update
// marketIdentifier is stored in editorData
const action = currentGroup?.editorData?.marketIdentifier ? 'upload' : 'submit';
// marketIdentifier is stored at top-level (same as agents)
const action = currentGroup?.marketIdentifier ? 'upload' : 'submit';
return (
<>

View File

@@ -45,8 +45,8 @@ export const useMarketGroupPublish = ({ action, onSuccess }: UseMarketGroupPubli
* Returns whether fork confirmation is needed and original group info
*/
const checkOwnership = useCallback(async (): Promise<CheckOwnershipResult> => {
// marketIdentifier is stored in editorData
const identifier = currentGroup?.editorData?.marketIdentifier as string | undefined;
// marketIdentifier is stored at top-level (same as agents)
const identifier = currentGroup?.marketIdentifier;
// No identifier means new group, no need to check
if (!identifier) {
@@ -150,27 +150,26 @@ export const useMarketGroupPublish = ({ action, onSuccess }: UseMarketGroupPubli
}),
...(currentGroupConfig.openingQuestions !== undefined &&
currentGroupConfig.openingQuestions.length > 0 && {
openingQuestions: currentGroupConfig.openingQuestions,
}),
openingQuestions: currentGroupConfig.openingQuestions,
}),
...(currentGroupConfig.allowDM !== undefined && { allowDM: currentGroupConfig.allowDM }),
...(currentGroupConfig.revealDM !== undefined && { revealDM: currentGroupConfig.revealDM }),
...(currentGroupConfig.revealDM !== undefined && {
revealDM: currentGroupConfig.revealDM,
}),
},
// Market requires at least 1 character for description
description: currentGroupMeta.description || 'No description provided',
// marketIdentifier is stored in editorData
identifier: currentGroup.editorData?.marketIdentifier as string | undefined,
// marketIdentifier is stored at top-level (same as agents)
identifier: currentGroup.marketIdentifier,
memberAgents,
name: currentGroupMeta.title || 'Untitled Group',
visibility: 'public', // TODO: Allow user to select visibility
});
// Save marketIdentifier to editorData if new group
// Save marketIdentifier at top-level if new group (same as agents)
if (result.isNewGroup) {
await updateGroupMeta({
editorData: {
...currentGroup.editorData,
marketIdentifier: result.identifier,
},
marketIdentifier: result.identifier,
});
}

View File

@@ -133,9 +133,11 @@ export const agentGroupRouter = router({
.object({
avatar: z.string().nullish(),
backgroundColor: z.string().nullish(),
chatConfig: z.any().nullish(),
description: z.string().nullish(),
model: z.string().nullish(),
params: z.any().nullish(),
plugins: z.array(z.string()).nullish(),
provider: z.string().nullish(),
systemRole: z.string().nullish(),
tags: z.array(z.string()).nullish(),

View File

@@ -177,8 +177,8 @@ const publishOrCreateSchema = z.object({
editorData: z.record(z.any()).optional(),
// Agent basic info
identifier: z.string().optional(),
// Optional - if not provided or not owned, will create new
identifier: z.string().nullish(),
// Optional - if not provided or not owned, will create new (allow null or undefined)
name: z.string(),
tags: z.array(z.string()).optional(),
tokenUsage: z.number().optional(),
@@ -312,12 +312,11 @@ export const agentRouter = router({
}
}),
/**
* Fork an agent
* POST /market/agent/:identifier/fork
*/
forkAgent: agentProcedure
forkAgent: agentProcedure
.input(
z.object({
identifier: z.string(),
@@ -385,13 +384,11 @@ forkAgent: agentProcedure
}
}),
/**
/**
* Get agent detail by identifier
* GET /market/agent/:identifier
*/
getAgentDetail: agentProcedure
getAgentDetail: agentProcedure
.input(z.object({ identifier: z.string() }))
.query(async ({ input, ctx }) => {
log('getAgentDetail input: %O', input);
@@ -409,14 +406,11 @@ getAgentDetail: agentProcedure
}
}),
/**
/**
* Get the fork source of an agent
* GET /market/agent/:identifier/fork-source
*/
getAgentForkSource: agentProcedure
getAgentForkSource: agentProcedure
.input(z.object({ identifier: z.string() }))
.query(async ({ input, ctx }) => {
log('getAgentForkSource input: %O', input);
@@ -470,16 +464,11 @@ getAgentForkSource: agentProcedure
}
}),
/**
/**
* Get all forks of an agent
* GET /market/agent/:identifier/forks
*/
getAgentForks: agentProcedure
getAgentForks: agentProcedure
.input(z.object({ identifier: z.string() }))
.query(async ({ input, ctx }) => {
log('getAgentForks input: %O', input);
@@ -533,17 +522,11 @@ getAgentForks: agentProcedure
}
}),
/**
/**
* Get own agents (requires authentication)
* GET /market/agent/own
*/
getOwnAgents: agentProcedure.input(paginationSchema.optional()).query(async ({ input, ctx }) => {
getOwnAgents: agentProcedure.input(paginationSchema.optional()).query(async ({ input, ctx }) => {
log('getOwnAgents input: %O', input);
try {
@@ -562,16 +545,11 @@ getOwnAgents: agentProcedure.input(paginationSchema.optional()).query(async ({ i
}
}),
/**
/**
* Publish an agent (make it visible in marketplace)
* POST /market/agent/:identifier/publish
*/
publishAgent: agentProcedure
publishAgent: agentProcedure
.input(z.object({ identifier: z.string() }))
.mutation(async ({ input, ctx }) => {
log('publishAgent input: %O', input);
@@ -589,11 +567,7 @@ publishAgent: agentProcedure
}
}),
/**
/**
* Unified publish or create agent flow
* This procedure handles the complete publish logic:
* 1. Check if identifier exists and if current user is owner
@@ -602,7 +576,7 @@ publishAgent: agentProcedure
*
* Returns: { identifier, isNewAgent, success }
*/
publishOrCreate: agentProcedure.input(publishOrCreateSchema).mutation(async ({ input, ctx }) => {
publishOrCreate: agentProcedure.input(publishOrCreateSchema).mutation(async ({ input, ctx }) => {
log('publishOrCreate input: %O', input);
const { identifier: inputIdentifier, name, ...versionData } = input;
@@ -684,13 +658,11 @@ publishOrCreate: agentProcedure.input(publishOrCreateSchema).mutation(async ({ i
}
}),
/**
/**
* Unpublish an agent (hide from marketplace, can be republished)
* POST /market/agent/:identifier/unpublish
*/
unpublishAgent: agentProcedure
unpublishAgent: agentProcedure
.input(z.object({ identifier: z.string() }))
.mutation(async ({ input, ctx }) => {
log('unpublishAgent input: %O', input);

View File

@@ -134,7 +134,7 @@ const publishOrCreateGroupSchema = z.object({
})
.optional(),
description: z.string(),
identifier: z.string().optional(),
identifier: z.string().nullish(), // Allow null or undefined
memberAgents: z.array(memberAgentSchema),
name: z.string(),
visibility: z.enum(['public', 'private', 'internal']).optional(),
@@ -200,12 +200,11 @@ export const agentGroupRouter = router({
}
}),
/**
* Deprecate agent group
* POST /market/agent-group/:identifier/deprecate
*/
deprecateAgentGroup: agentGroupProcedure
deprecateAgentGroup: agentGroupProcedure
.input(z.object({ identifier: z.string() }))
.mutation(async ({ input, ctx }) => {
log('deprecateAgentGroup input: %O', input);
@@ -259,13 +258,11 @@ deprecateAgentGroup: agentGroupProcedure
}
}),
/**
/**
* Fork an agent group
* POST /market/agent-group/:identifier/fork
*/
forkAgentGroup: agentGroupProcedure
forkAgentGroup: agentGroupProcedure
.input(
z.object({
identifier: z.string(),
@@ -338,13 +335,11 @@ forkAgentGroup: agentGroupProcedure
}
}),
/**
/**
* Get the fork source of an agent group
* GET /market/agent-group/:identifier/fork-source
*/
getAgentGroupForkSource: agentGroupProcedure
getAgentGroupForkSource: agentGroupProcedure
.input(z.object({ identifier: z.string() }))
.query(async ({ input, ctx }) => {
log('getAgentGroupForkSource input: %O', input);
@@ -398,13 +393,11 @@ getAgentGroupForkSource: agentGroupProcedure
}
}),
/**
/**
* Get all forks of an agent group
* GET /market/agent-group/:identifier/forks
*/
getAgentGroupForks: agentGroupProcedure
getAgentGroupForks: agentGroupProcedure
.input(z.object({ identifier: z.string() }))
.query(async ({ input, ctx }) => {
log('getAgentGroupForks input: %O', input);
@@ -458,13 +451,11 @@ getAgentGroupForks: agentGroupProcedure
}
}),
/**
/**
* Publish agent group
* POST /market/agent-group/:identifier/publish
*/
publishAgentGroup: agentGroupProcedure
publishAgentGroup: agentGroupProcedure
.input(z.object({ identifier: z.string() }))
.mutation(async ({ input, ctx }) => {
log('publishAgentGroup input: %O', input);
@@ -518,15 +509,13 @@ publishAgentGroup: agentGroupProcedure
}
}),
/**
/**
* Unified publish or create agent group flow
* 1. Check if identifier exists and if current user is owner
* 2. If not owner or no identifier, create new group
* 3. Create new version for the group if updating
*/
publishOrCreate: agentGroupProcedure
publishOrCreate: agentGroupProcedure
.input(publishOrCreateGroupSchema)
.mutation(async ({ input, ctx }) => {
log('publishOrCreate input: %O', input);
@@ -614,12 +603,11 @@ publishOrCreate: agentGroupProcedure
}
}),
/**
* Unpublish agent group
* POST /market/agent-group/:identifier/unpublish
*/
unpublishAgentGroup: agentGroupProcedure
unpublishAgentGroup: agentGroupProcedure
.input(z.object({ identifier: z.string() }))
.mutation(async ({ input, ctx }) => {
log('unpublishAgentGroup input: %O', input);