🐛 fix: slove when use copy & install group from market, the member system Role is lost (#11585)

fix: slove when use copy & install group from market, the member systemRole not found
This commit is contained in:
Shinji-Li
2026-01-18 22:24:22 +08:00
committed by GitHub
parent a6754c38a5
commit 9b73ad78f9
4 changed files with 128 additions and 17 deletions

View File

@@ -15,8 +15,14 @@ import {
import { LobeChatDatabase } from '../../type';
export interface SupervisorAgentConfig {
avatar?: string;
backgroundColor?: string;
description?: string;
model?: string;
params?: any;
provider?: string;
systemRole?: string;
tags?: string[];
title?: string;
}
@@ -164,8 +170,14 @@ export class AgentGroupRepository {
const [supervisorAgent] = await this.db
.insert(agents)
.values({
avatar: supervisorConfig?.avatar,
backgroundColor: supervisorConfig?.backgroundColor,
description: supervisorConfig?.description,
model: supervisorConfig?.model,
params: supervisorConfig?.params,
provider: supervisorConfig?.provider,
systemRole: supervisorConfig?.systemRole,
tags: supervisorConfig?.tags,
title: supervisorConfig?.title ?? 'Supervisor',
userId: this.userId,
virtual: true,
@@ -356,7 +368,12 @@ export class AgentGroupRepository {
const [newGroup] = await trx
.insert(chatGroups)
.values({
avatar: sourceGroup.avatar,
backgroundColor: sourceGroup.backgroundColor,
config: sourceGroup.config,
content: sourceGroup.content,
description: sourceGroup.description,
editorData: sourceGroup.editorData,
pinned: sourceGroup.pinned,
title: newTitle || (sourceGroup.title ? `${sourceGroup.title} (Copy)` : 'Copy'),
userId: this.userId,
@@ -368,8 +385,14 @@ export class AgentGroupRepository {
const [newSupervisor] = await trx
.insert(agents)
.values({
avatar: supervisorAgent?.avatar,
backgroundColor: supervisorAgent?.backgroundColor,
description: supervisorAgent?.description,
model: supervisorAgent?.model,
params: supervisorAgent?.params,
provider: supervisorAgent?.provider,
systemRole: supervisorAgent?.systemRole,
tags: supervisorAgent?.tags,
title: supervisorAgent?.title || 'Supervisor',
userId: this.userId,
virtual: true,

View File

@@ -87,6 +87,42 @@ const AddGroupAgent = memo<{ mobile?: boolean }>(() => {
return;
}
// Find supervisor from memberAgents
const supervisorMember = memberAgents.find((member: any) => {
const agent = member.agent || member;
const role = member.role || agent.role;
return role === 'supervisor';
});
// Prepare supervisor config
let supervisorConfig;
if (supervisorMember) {
// Type assertion needed because actual API data structure differs from type definition
const member = supervisorMember as any;
const agent = member.agent || member;
const currentVersion = member.currentVersion || member;
const rawConfig = {
avatar: currentVersion.avatar,
backgroundColor: currentVersion.backgroundColor,
description: currentVersion.description,
model: currentVersion.config?.model || currentVersion.model,
params: currentVersion.config?.params || currentVersion.params,
provider: currentVersion.config?.provider || currentVersion.provider,
systemRole:
currentVersion.config?.systemRole ||
currentVersion.config?.systemPrompt ||
currentVersion.systemRole ||
currentVersion.content,
tags: currentVersion.tags,
title: currentVersion.name || agent.name || 'Supervisor',
};
// Filter out null/undefined values
supervisorConfig = Object.fromEntries(
// eslint-disable-next-line eqeqeq, @typescript-eslint/no-unused-vars
Object.entries(rawConfig).filter(([_, v]) => v != null),
);
}
// Prepare group config
const groupConfig = {
config: {
@@ -95,30 +131,46 @@ const AddGroupAgent = memo<{ mobile?: boolean }>(() => {
openingQuestions: config.openingQuestions,
revealDM: config.revealDM,
},
content: config.systemRole,
// Group content is the supervisor's systemRole (for backward compatibility)
content: supervisorConfig?.systemRole || config.systemRole,
...meta,
};
// Prepare member agents from market data
const members = memberAgents.map((member: any) => {
const agent = member.agent || member;
const currentVersion = member.currentVersion || member;
return {
avatar: currentVersion.avatar,
backgroundColor: currentVersion.backgroundColor,
description: currentVersion.description,
model: currentVersion.model,
plugins: currentVersion.plugins,
provider: currentVersion.provider,
systemRole: currentVersion.systemRole || currentVersion.content,
tags: currentVersion.tags,
title: currentVersion.name || agent.name,
};
});
// Filter out supervisor role as it will be created separately using supervisorConfig
const members = memberAgents
.filter((member: any) => {
const agent = member.agent || member;
const role = member.role || agent.role;
return role !== 'supervisor';
})
.map((member: any) => {
const agent = member.agent || member;
const currentVersion = member.currentVersion || member;
return {
avatar: currentVersion.avatar,
backgroundColor: currentVersion.backgroundColor,
description: currentVersion.description,
model: currentVersion.config?.model || currentVersion.model,
plugins: currentVersion.plugins,
provider: currentVersion.config?.provider || currentVersion.provider,
systemRole:
currentVersion.config?.systemRole ||
currentVersion.config?.systemPrompt ||
currentVersion.systemRole ||
currentVersion.content,
tags: currentVersion.tags,
title: currentVersion.name || agent.name,
};
});
try {
// Create group with all members in one request
const result = await chatGroupService.createGroupWithMembers(groupConfig, members);
const result = await chatGroupService.createGroupWithMembers(
groupConfig,
members,
supervisorConfig,
);
// Refresh group list
await loadGroups();

View File

@@ -129,6 +129,19 @@ export const agentGroupRouter = router({
})
.partial(),
),
supervisorConfig: z
.object({
avatar: z.string().nullish(),
backgroundColor: z.string().nullish(),
description: z.string().nullish(),
model: z.string().nullish(),
params: z.any().nullish(),
provider: z.string().nullish(),
systemRole: z.string().nullish(),
tags: z.array(z.string()).nullish(),
title: z.string().nullish(),
})
.optional(),
}),
)
.mutation(async ({ input, ctx }) => {
@@ -144,6 +157,14 @@ export const agentGroupRouter = router({
const memberAgentIds = createdAgents.map((agent) => agent.id);
// 2. Create group with supervisor and member agents
// Filter out null/undefined values from supervisorConfig
const supervisorConfig = input.supervisorConfig
? Object.fromEntries(
// eslint-disable-next-line @typescript-eslint/no-unused-vars, eqeqeq
Object.entries(input.supervisorConfig).filter(([_, v]) => v != null),
)
: undefined;
const { group, supervisorAgentId } = await ctx.agentGroupRepo.createGroupWithSupervisor(
{
...input.groupConfig,
@@ -152,6 +173,7 @@ export const agentGroupRouter = router({
),
},
memberAgentIds,
supervisorConfig as any,
);
return { agentIds: memberAgentIds, groupId: group.id, supervisorAgentId };

View File

@@ -20,6 +20,18 @@ export interface GroupMemberConfig {
title?: string;
}
export interface SupervisorConfig {
avatar?: string;
backgroundColor?: string;
description?: string;
model?: string;
params?: any;
provider?: string;
systemRole?: string;
tags?: string[];
title?: string;
}
class ChatGroupService {
/**
* Create a group with a supervisor agent.
@@ -42,6 +54,7 @@ class ChatGroupService {
createGroupWithMembers = (
groupConfig: Omit<NewChatGroup, 'userId'>,
members: GroupMemberConfig[],
supervisorConfig?: SupervisorConfig,
): Promise<{ agentIds: string[]; groupId: string; supervisorAgentId: string }> => {
return lambdaClient.group.createGroupWithMembers.mutate({
groupConfig: {
@@ -49,6 +62,7 @@ class ChatGroupService {
config: groupConfig.config as any,
},
members: members as Partial<AgentItem>[],
supervisorConfig,
});
};