@lobehub/lobehub 2.0.0-next.273 → 2.0.0-next.274

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.
Files changed (227) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/changelog/v1.json +9 -0
  3. package/locales/ar/chat.json +7 -0
  4. package/locales/ar/models.json +2 -3
  5. package/locales/ar/plugin.json +22 -1
  6. package/locales/bg-BG/chat.json +7 -0
  7. package/locales/bg-BG/models.json +3 -3
  8. package/locales/bg-BG/plugin.json +22 -1
  9. package/locales/de-DE/chat.json +7 -0
  10. package/locales/de-DE/models.json +3 -4
  11. package/locales/de-DE/plugin.json +22 -1
  12. package/locales/en-US/chat.json +7 -0
  13. package/locales/en-US/models.json +5 -5
  14. package/locales/en-US/plugin.json +22 -1
  15. package/locales/es-ES/chat.json +7 -0
  16. package/locales/es-ES/models.json +3 -4
  17. package/locales/es-ES/plugin.json +22 -1
  18. package/locales/fa-IR/chat.json +7 -0
  19. package/locales/fa-IR/models.json +3 -4
  20. package/locales/fa-IR/plugin.json +22 -1
  21. package/locales/fr-FR/chat.json +7 -0
  22. package/locales/fr-FR/models.json +50 -3
  23. package/locales/fr-FR/plugin.json +22 -1
  24. package/locales/it-IT/chat.json +7 -0
  25. package/locales/it-IT/models.json +3 -3
  26. package/locales/it-IT/plugin.json +22 -1
  27. package/locales/ja-JP/chat.json +7 -0
  28. package/locales/ja-JP/models.json +43 -4
  29. package/locales/ja-JP/plugin.json +22 -1
  30. package/locales/ko-KR/chat.json +7 -0
  31. package/locales/ko-KR/models.json +3 -4
  32. package/locales/ko-KR/plugin.json +22 -1
  33. package/locales/nl-NL/chat.json +7 -0
  34. package/locales/nl-NL/models.json +51 -3
  35. package/locales/nl-NL/plugin.json +22 -1
  36. package/locales/pl-PL/chat.json +7 -0
  37. package/locales/pl-PL/models.json +3 -3
  38. package/locales/pl-PL/plugin.json +22 -1
  39. package/locales/pt-BR/chat.json +7 -0
  40. package/locales/pt-BR/models.json +3 -4
  41. package/locales/pt-BR/plugin.json +22 -1
  42. package/locales/ru-RU/chat.json +7 -0
  43. package/locales/ru-RU/models.json +3 -4
  44. package/locales/ru-RU/plugin.json +22 -1
  45. package/locales/tr-TR/chat.json +7 -0
  46. package/locales/tr-TR/models.json +3 -4
  47. package/locales/tr-TR/plugin.json +22 -1
  48. package/locales/vi-VN/chat.json +7 -0
  49. package/locales/vi-VN/models.json +3 -3
  50. package/locales/vi-VN/plugin.json +22 -1
  51. package/locales/zh-CN/chat.json +7 -0
  52. package/locales/zh-CN/models.json +54 -4
  53. package/locales/zh-CN/plugin.json +22 -1
  54. package/locales/zh-TW/chat.json +7 -0
  55. package/locales/zh-TW/models.json +43 -4
  56. package/locales/zh-TW/plugin.json +22 -1
  57. package/package.json +1 -1
  58. package/packages/builtin-tool-agent-builder/package.json +1 -0
  59. package/packages/builtin-tool-agent-builder/src/client/Inspector/GetAvailableModels/index.tsx +66 -0
  60. package/packages/builtin-tool-agent-builder/src/client/Inspector/InstallPlugin/index.tsx +63 -0
  61. package/packages/builtin-tool-agent-builder/src/client/Inspector/SearchMarketTools/index.tsx +64 -0
  62. package/packages/builtin-tool-agent-builder/src/client/Inspector/UpdateConfig/index.tsx +94 -0
  63. package/packages/builtin-tool-agent-builder/src/client/Inspector/UpdatePrompt/index.tsx +96 -0
  64. package/packages/builtin-tool-agent-builder/src/client/Inspector/index.ts +29 -0
  65. package/packages/builtin-tool-agent-builder/src/client/index.ts +13 -0
  66. package/packages/builtin-tool-agent-builder/src/executor.ts +132 -0
  67. package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/ExecuteCode/index.tsx +5 -14
  68. package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/RunCommand/index.tsx +5 -13
  69. package/packages/builtin-tool-group-agent-builder/package.json +7 -1
  70. package/packages/builtin-tool-group-agent-builder/src/ExecutionRuntime/index.ts +331 -87
  71. package/packages/builtin-tool-group-agent-builder/src/client/Inspector/BatchCreateAgents/index.tsx +110 -0
  72. package/packages/builtin-tool-group-agent-builder/src/client/Inspector/CreateAgent/index.tsx +72 -0
  73. package/packages/builtin-tool-group-agent-builder/src/client/Inspector/InviteAgent/index.tsx +57 -0
  74. package/packages/builtin-tool-group-agent-builder/src/client/Inspector/RemoveAgent/index.tsx +57 -0
  75. package/packages/builtin-tool-group-agent-builder/src/client/Inspector/SearchAgent/index.tsx +66 -0
  76. package/packages/builtin-tool-group-agent-builder/src/client/Inspector/UpdateAgentPrompt/index.tsx +120 -0
  77. package/packages/builtin-tool-group-agent-builder/src/client/Inspector/UpdateGroup/index.tsx +87 -0
  78. package/packages/builtin-tool-group-agent-builder/src/client/Inspector/UpdateGroupPrompt/index.tsx +99 -0
  79. package/packages/builtin-tool-group-agent-builder/src/client/Inspector/index.ts +52 -0
  80. package/packages/builtin-tool-group-agent-builder/src/client/Render/BatchCreateAgents.tsx +103 -0
  81. package/packages/builtin-tool-group-agent-builder/src/client/Render/UpdateAgentPrompt/index.tsx +36 -0
  82. package/packages/builtin-tool-group-agent-builder/src/client/Render/UpdateGroupPrompt/index.tsx +36 -0
  83. package/packages/builtin-tool-group-agent-builder/src/client/Render/index.ts +16 -0
  84. package/packages/builtin-tool-group-agent-builder/src/client/Streaming/BatchCreateAgents/index.tsx +88 -0
  85. package/packages/builtin-tool-group-agent-builder/src/client/Streaming/UpdateAgentPrompt/index.tsx +37 -0
  86. package/packages/builtin-tool-group-agent-builder/src/client/Streaming/UpdateGroupPrompt/index.tsx +35 -0
  87. package/packages/builtin-tool-group-agent-builder/src/client/Streaming/index.ts +22 -0
  88. package/packages/builtin-tool-group-agent-builder/src/client/index.ts +26 -0
  89. package/packages/builtin-tool-group-agent-builder/src/executor.ts +284 -0
  90. package/packages/builtin-tool-group-agent-builder/src/index.ts +1 -14
  91. package/packages/builtin-tool-group-agent-builder/src/manifest.ts +160 -15
  92. package/packages/builtin-tool-group-agent-builder/src/systemRole.ts +232 -46
  93. package/packages/builtin-tool-group-agent-builder/src/types.ts +191 -41
  94. package/packages/builtin-tool-group-management/src/client/Inspector/Broadcast/index.tsx +2 -2
  95. package/packages/builtin-tool-group-management/src/manifest.ts +1 -1
  96. package/packages/builtin-tool-gtd/src/client/Inspector/ClearTodos/index.tsx +5 -11
  97. package/packages/builtin-tool-gtd/src/client/Inspector/CompleteTodos/index.tsx +3 -9
  98. package/packages/builtin-tool-gtd/src/client/Inspector/CreatePlan/index.tsx +6 -15
  99. package/packages/builtin-tool-gtd/src/client/Inspector/CreateTodos/index.tsx +3 -9
  100. package/packages/builtin-tool-gtd/src/client/Inspector/ExecTask/index.tsx +6 -17
  101. package/packages/builtin-tool-gtd/src/client/Inspector/RemoveTodos/index.tsx +3 -9
  102. package/packages/builtin-tool-gtd/src/client/Inspector/UpdatePlan/index.tsx +3 -9
  103. package/packages/builtin-tool-gtd/src/client/Inspector/UpdateTodos/index.tsx +3 -9
  104. package/packages/builtin-tool-knowledge-base/src/client/Inspector/ReadKnowledge/index.tsx +4 -16
  105. package/packages/builtin-tool-knowledge-base/src/client/Inspector/SearchKnowledgeBase/index.tsx +5 -16
  106. package/packages/builtin-tool-local-system/src/client/Inspector/EditLocalFile/index.tsx +4 -12
  107. package/packages/builtin-tool-local-system/src/client/Inspector/GlobLocalFiles/index.tsx +5 -13
  108. package/packages/builtin-tool-local-system/src/client/Inspector/GrepContent/index.tsx +5 -16
  109. package/packages/builtin-tool-local-system/src/client/Inspector/ListLocalFiles/index.tsx +5 -16
  110. package/packages/builtin-tool-local-system/src/client/Inspector/ReadLocalFile/index.tsx +5 -16
  111. package/packages/builtin-tool-local-system/src/client/Inspector/RenameLocalFile/index.tsx +5 -11
  112. package/packages/builtin-tool-local-system/src/client/Inspector/RunCommand/index.tsx +5 -13
  113. package/packages/builtin-tool-local-system/src/client/Inspector/SearchLocalFiles/index.tsx +5 -16
  114. package/packages/builtin-tool-local-system/src/client/Inspector/WriteLocalFile/index.tsx +6 -15
  115. package/packages/builtin-tool-notebook/src/client/Inspector/CreateDocument/index.tsx +7 -15
  116. package/packages/builtin-tool-page-agent/src/client/Inspector/EditTitle/index.tsx +5 -14
  117. package/packages/builtin-tool-page-agent/src/client/Inspector/GetPageContent/index.tsx +7 -8
  118. package/packages/builtin-tool-page-agent/src/client/Inspector/InitPage/index.tsx +4 -10
  119. package/packages/builtin-tool-page-agent/src/client/Inspector/ModifyNodes/index.tsx +3 -9
  120. package/packages/builtin-tool-page-agent/src/client/Inspector/ReplaceText/index.tsx +5 -11
  121. package/packages/builtin-tool-web-browsing/src/client/Inspector/CrawlMultiPages/index.tsx +6 -15
  122. package/packages/builtin-tool-web-browsing/src/client/Inspector/CrawlSinglePage/index.tsx +6 -15
  123. package/packages/builtin-tool-web-browsing/src/client/Inspector/Search/index.tsx +4 -15
  124. package/packages/database/src/models/chatGroup.ts +1 -1
  125. package/packages/model-bank/src/aiModels/aihubmix.ts +2 -1
  126. package/packages/model-bank/src/aiModels/google.ts +2 -1
  127. package/packages/model-bank/src/aiModels/infiniai.ts +9 -6
  128. package/packages/model-bank/src/aiModels/minimax.ts +9 -5
  129. package/packages/model-bank/src/aiModels/ollamacloud.ts +4 -2
  130. package/packages/model-bank/src/aiModels/vertexai.ts +2 -1
  131. package/packages/types/src/agentGroup/index.ts +8 -0
  132. package/patches/@upstash__qstash.patch +13 -1
  133. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Header/Nav.tsx +1 -1
  134. package/src/app/[variants]/(main)/agent/cron/[cronId]/index.tsx +4 -3
  135. package/src/app/[variants]/(main)/agent/profile/features/ProfileEditor/index.tsx +1 -1
  136. package/src/app/[variants]/(main)/agent/profile/features/store/action.ts +18 -21
  137. package/src/app/[variants]/(main)/group/_layout/GroupIdSync.tsx +6 -1
  138. package/src/app/[variants]/(main)/group/_layout/Sidebar/GroupConfig/AgentProfilePopup.tsx +29 -21
  139. package/src/app/[variants]/(main)/group/_layout/Sidebar/GroupConfig/GroupMember.tsx +1 -0
  140. package/src/app/[variants]/(main)/group/_layout/Sidebar/GroupConfig/GroupMemberItem.tsx +35 -18
  141. package/src/app/[variants]/(main)/group/_layout/Sidebar/Header/AddTopicButon.tsx +2 -10
  142. package/src/app/[variants]/(main)/group/_layout/Sidebar/Header/Nav.tsx +10 -2
  143. package/src/app/[variants]/(main)/group/_layout/Sidebar/Header/index.tsx +1 -2
  144. package/src/app/[variants]/(main)/group/profile/features/AgentBuilder/AgentBuilderProvider.tsx +1 -0
  145. package/src/app/[variants]/(main)/group/profile/features/AgentBuilder/TopicSelector.tsx +15 -9
  146. package/src/app/[variants]/(main)/group/profile/features/AgentBuilder/index.tsx +12 -6
  147. package/src/app/[variants]/(main)/group/profile/features/{ProfileEditor/AgentHeader.tsx → GroupProfile/GroupHeader.tsx} +22 -29
  148. package/src/app/[variants]/(main)/group/profile/features/GroupProfile/index.tsx +96 -0
  149. package/src/app/[variants]/(main)/group/profile/features/Header/AgentBuilderToggle.tsx +3 -4
  150. package/src/app/[variants]/(main)/group/profile/features/Header/AutoSaveHint.tsx +11 -7
  151. package/src/app/[variants]/(main)/group/profile/features/Header/ChromeTabs/index.tsx +147 -0
  152. package/src/app/[variants]/(main)/group/profile/features/Header/index.tsx +104 -13
  153. package/src/app/[variants]/(main)/group/profile/features/MemberProfile/AgentHeader.tsx +222 -0
  154. package/src/app/[variants]/(main)/group/profile/features/MemberProfile/index.tsx +155 -0
  155. package/src/app/[variants]/(main)/group/profile/features/ProfileHydration.tsx +63 -5
  156. package/src/app/[variants]/(main)/group/profile/index.tsx +34 -37
  157. package/src/app/[variants]/(mobile)/(home)/_layout/SessionHydration.tsx +1 -1
  158. package/src/app/[variants]/(mobile)/(home)/features/SessionListContent/List/Item/index.tsx +1 -1
  159. package/src/features/AgentBuilder/index.tsx +16 -1
  160. package/src/features/Conversation/Messages/AssistantGroup/Tool/Inspector/StatusIndicator.tsx +3 -2
  161. package/src/features/EditorCanvas/EditorCanvas.test.tsx +206 -0
  162. package/src/features/EditorCanvas/EditorDataMode.tsx +53 -19
  163. package/src/features/EditorModal/index.tsx +2 -2
  164. package/src/features/NavPanel/components/SessionHydration.tsx +1 -1
  165. package/src/features/ShareModal/ShareImage/ChatList/index.tsx +1 -1
  166. package/src/features/ShareModal/SharePdf/index.tsx +1 -1
  167. package/src/hooks/useBidirectionalQuerySync.ts +112 -0
  168. package/src/locales/default/chat.ts +10 -0
  169. package/src/locales/default/plugin.ts +22 -1
  170. package/src/server/modules/AgentRuntime/RuntimeExecutors.ts +45 -45
  171. package/src/server/modules/KeyVaultsEncrypt/index.ts +6 -6
  172. package/src/server/modules/S3/index.ts +1 -1
  173. package/src/server/routers/lambda/agent.ts +24 -0
  174. package/src/server/routers/lambda/agentGroup.ts +39 -0
  175. package/src/services/agent.ts +22 -0
  176. package/src/services/chatGroup/index.ts +14 -0
  177. package/src/store/agent/selectors/selectors.ts +3 -0
  178. package/src/store/agentGroup/initialState.ts +6 -0
  179. package/src/store/agentGroup/selectors/byId.ts +3 -1
  180. package/src/store/agentGroup/selectors/current.ts +2 -2
  181. package/src/store/agentGroup/slices/lifecycle.ts +18 -0
  182. package/src/store/chat/agents/__tests__/createAgentExecutors/fixtures/mockStore.ts +1 -1
  183. package/src/store/chat/slices/aiAgent/actions/__tests__/agentGroup.test.ts +4 -1
  184. package/src/store/chat/slices/aiAgent/actions/agentGroup.ts +1 -1
  185. package/src/store/chat/slices/aiChat/actions/__tests__/conversationLifecycle.test.ts +65 -0
  186. package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +2 -1
  187. package/src/store/chat/slices/builtinTool/actions/__tests__/search.test.ts +1 -1
  188. package/src/store/chat/slices/builtinTool/actions/index.ts +1 -6
  189. package/src/store/chat/slices/message/action.test.ts +5 -5
  190. package/src/store/chat/slices/message/actions/publicApi.ts +5 -5
  191. package/src/store/chat/slices/message/initialState.ts +0 -5
  192. package/src/store/chat/slices/message/selectors/displayMessage.test.ts +4 -4
  193. package/src/store/chat/slices/plugin/action.test.ts +54 -19
  194. package/src/store/chat/slices/plugin/actions/pluginTypes.ts +15 -21
  195. package/src/store/chat/slices/topic/action.test.ts +74 -24
  196. package/src/store/chat/slices/topic/action.ts +21 -13
  197. package/src/store/chat/slices/topic/selectors.test.ts +1 -1
  198. package/src/store/global/initialState.ts +10 -0
  199. package/src/store/global/selectors/systemStatus.ts +5 -0
  200. package/src/store/groupProfile/action.ts +168 -0
  201. package/src/store/groupProfile/index.ts +16 -0
  202. package/src/{app/[variants]/(main)/group/profile/features/store → store/groupProfile}/initialState.ts +17 -0
  203. package/src/store/groupProfile/selectors.ts +13 -0
  204. package/src/store/tool/slices/builtin/executors/index.ts +4 -0
  205. package/src/styles/text.ts +16 -0
  206. package/src/tools/inspectors.ts +13 -0
  207. package/src/tools/renders.ts +3 -0
  208. package/src/tools/streamings.ts +8 -0
  209. package/src/app/[variants]/(main)/group/profile/features/EditorCanvas/TypoBar.tsx +0 -129
  210. package/src/app/[variants]/(main)/group/profile/features/EditorCanvas/index.tsx +0 -138
  211. package/src/app/[variants]/(main)/group/profile/features/EditorCanvas/useSlashItems.tsx +0 -139
  212. package/src/app/[variants]/(main)/group/profile/features/ProfileEditor/index.tsx +0 -82
  213. package/src/app/[variants]/(main)/group/profile/features/ProfileProvider.tsx +0 -20
  214. package/src/app/[variants]/(main)/group/profile/features/StoreUpdater.tsx +0 -24
  215. package/src/app/[variants]/(main)/group/profile/features/store/action.ts +0 -163
  216. package/src/app/[variants]/(main)/group/profile/features/store/index.ts +0 -23
  217. package/src/app/[variants]/(main)/group/profile/features/store/selectors.ts +0 -7
  218. package/src/features/EditorModal/EditorCanvas.tsx +0 -84
  219. package/src/features/EditorModal/Typobar.tsx +0 -139
  220. package/src/store/chat/slices/builtinTool/actions/agentBuilder.ts +0 -192
  221. package/src/store/chat/slices/builtinTool/actions/groupAgentBuilder.ts +0 -242
  222. package/src/tools/executionRuntimes.ts +0 -14
  223. /package/src/app/[variants]/(main)/group/profile/features/{ProfileEditor → MemberProfile}/AgentTool.tsx +0 -0
  224. /package/src/app/[variants]/(main)/group/profile/features/{ProfileEditor → MemberProfile}/MentionList/MentionDropdown.tsx +0 -0
  225. /package/src/app/[variants]/(main)/group/profile/features/{ProfileEditor → MemberProfile}/MentionList/index.tsx +0 -0
  226. /package/src/app/[variants]/(main)/group/profile/features/{ProfileEditor → MemberProfile}/MentionList/types.ts +0 -0
  227. /package/src/app/[variants]/(main)/group/profile/features/{ProfileEditor → MemberProfile}/MentionList/useMentionItems.tsx +0 -0
@@ -1,18 +1,27 @@
1
1
  import type { BuiltinServerRuntimeOutput } from '@lobechat/types';
2
2
 
3
- import { chatGroupService } from '@/services/chatGroup';
3
+ import { agentService } from '@/services/agent';
4
+ import { type GroupMemberConfig, chatGroupService } from '@/services/chatGroup';
5
+ import { useAgentStore } from '@/store/agent';
4
6
  import { getChatGroupStoreState } from '@/store/agentGroup';
5
7
  import { agentGroupSelectors } from '@/store/agentGroup/selectors';
6
8
 
7
9
  import type {
10
+ BatchCreateAgentsParams,
11
+ BatchCreateAgentsState,
12
+ CreateAgentParams,
13
+ CreateAgentState,
8
14
  InviteAgentParams,
9
15
  InviteAgentState,
10
16
  RemoveAgentParams,
11
17
  RemoveAgentState,
12
- UpdateGroupConfigParams,
13
- UpdateGroupConfigState,
18
+ SearchAgentParams,
19
+ SearchAgentState,
20
+ UpdateAgentPromptParams,
21
+ UpdateGroupParams,
14
22
  UpdateGroupPromptParams,
15
23
  UpdateGroupPromptState,
24
+ UpdateGroupState,
16
25
  } from '../types';
17
26
 
18
27
  /**
@@ -21,7 +30,184 @@ import type {
21
30
  * Extends AgentBuilder functionality with group-specific operations
22
31
  */
23
32
  export class GroupAgentBuilderExecutionRuntime {
24
- // ==================== Group-specific Operations ====================
33
+ // ==================== Group Member Management ====================
34
+
35
+ /**
36
+ * Search for agents that can be invited to the group
37
+ */
38
+ async searchAgent(args: SearchAgentParams): Promise<BuiltinServerRuntimeOutput> {
39
+ const { query, limit = 10 } = args;
40
+
41
+ try {
42
+ const results = await agentService.queryAgents({ keyword: query, limit });
43
+
44
+ const agents = results.map((agent) => ({
45
+ avatar: agent.avatar,
46
+ description: agent.description,
47
+ id: agent.id,
48
+ title: agent.title,
49
+ }));
50
+
51
+ const total = agents.length;
52
+
53
+ if (total === 0) {
54
+ return {
55
+ content: query
56
+ ? `No agents found matching "${query}".`
57
+ : 'No agents found. You can create a new agent or search with different keywords.',
58
+ state: { agents: [], query, total: 0 } as SearchAgentState,
59
+ success: true,
60
+ };
61
+ }
62
+
63
+ // Format agents list for LLM consumption
64
+ const agentList = agents
65
+ .map(
66
+ (a, i) =>
67
+ `${i + 1}. ${a.title || 'Untitled'} (ID: ${a.id})${a.description ? ` - ${a.description}` : ''}`,
68
+ )
69
+ .join('\n');
70
+
71
+ return {
72
+ content: query
73
+ ? `Found ${total} agent${total > 1 ? 's' : ''} matching "${query}":\n${agentList}`
74
+ : `Found ${total} agent${total > 1 ? 's' : ''}:\n${agentList}`,
75
+ state: { agents, query, total } as SearchAgentState,
76
+ success: true,
77
+ };
78
+ } catch (error) {
79
+ const err = error as Error;
80
+ return {
81
+ content: `Failed to search agents: ${err.message}`,
82
+ error,
83
+ success: false,
84
+ };
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Create a new agent and add it to the group
90
+ */
91
+ async createAgent(groupId: string, args: CreateAgentParams): Promise<BuiltinServerRuntimeOutput> {
92
+ try {
93
+ const state = getChatGroupStoreState();
94
+ const group = agentGroupSelectors.getGroupById(groupId)(state);
95
+
96
+ if (!group) {
97
+ return {
98
+ content: 'Group not found',
99
+ error: 'Group not found',
100
+ success: false,
101
+ };
102
+ }
103
+
104
+ // Create a virtual agent only (no session needed for group agents)
105
+ // Map 'tools' from LLM input to 'plugins' for internal API
106
+ const result = await agentService.createAgentOnly({
107
+ config: {
108
+ avatar: args.avatar,
109
+ description: args.description,
110
+ plugins: args.tools,
111
+ systemRole: args.systemRole,
112
+ title: args.title,
113
+ virtual: true,
114
+ },
115
+ groupId,
116
+ });
117
+
118
+ if (!result.agentId) {
119
+ return {
120
+ content: 'Failed to create agent: No agent ID returned',
121
+ success: false,
122
+ };
123
+ }
124
+
125
+ // Refresh the group detail in the store
126
+ await state.refreshGroupDetail(groupId);
127
+
128
+ return {
129
+ content: `Successfully created agent "${args.title}" and added it to the group.`,
130
+ state: {
131
+ agentId: result.agentId,
132
+ success: true,
133
+ title: args.title,
134
+ } as CreateAgentState,
135
+ success: true,
136
+ };
137
+ } catch (error) {
138
+ const err = error as Error;
139
+ return {
140
+ content: `Failed to create agent: ${err.message}`,
141
+ error,
142
+ success: false,
143
+ };
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Create multiple agents at once and add them to the group
149
+ * Uses batch API for efficiency (single request instead of N requests)
150
+ */
151
+ async batchCreateAgents(
152
+ groupId: string,
153
+ args: BatchCreateAgentsParams,
154
+ ): Promise<BuiltinServerRuntimeOutput> {
155
+ try {
156
+ const state = getChatGroupStoreState();
157
+ const group = agentGroupSelectors.getGroupById(groupId)(state);
158
+
159
+ if (!group) {
160
+ return {
161
+ content: 'Group not found',
162
+ error: 'Group not found',
163
+ success: false,
164
+ };
165
+ }
166
+
167
+ // Use batch API to create all agents in one request
168
+ // Map 'tools' from LLM input to 'plugins' for internal API
169
+ const agentConfigs: GroupMemberConfig[] = args.agents.map((agentDef) => ({
170
+ avatar: agentDef.avatar,
171
+ description: agentDef.description,
172
+ plugins: agentDef.tools,
173
+ systemRole: agentDef.systemRole,
174
+ title: agentDef.title,
175
+ }));
176
+
177
+ const { agents: createdAgents } = await chatGroupService.batchCreateAgentsInGroup(
178
+ groupId,
179
+ agentConfigs,
180
+ );
181
+
182
+ // Refresh the group detail in the store
183
+ await state.refreshGroupDetail(groupId);
184
+
185
+ const results = createdAgents.map((agent, index) => ({
186
+ agentId: agent.id,
187
+ success: true,
188
+ title: args.agents[index].title,
189
+ }));
190
+
191
+ const createdList = results.map((r) => `- ${r.title} (ID: ${r.agentId})`).join('\n');
192
+
193
+ return {
194
+ content: `Successfully created ${results.length} agent${results.length > 1 ? 's' : ''}:\n${createdList}`,
195
+ state: {
196
+ agents: results,
197
+ failedCount: 0,
198
+ successCount: results.length,
199
+ } as BatchCreateAgentsState,
200
+ success: true,
201
+ };
202
+ } catch (error) {
203
+ const err = error as Error;
204
+ return {
205
+ content: `Failed to create agents: ${err.message}`,
206
+ error,
207
+ success: false,
208
+ };
209
+ }
210
+ }
25
211
 
26
212
  /**
27
213
  * Invite an agent to the group
@@ -149,64 +335,58 @@ export class GroupAgentBuilderExecutionRuntime {
149
335
  }
150
336
  }
151
337
 
338
+ // ==================== Group Configuration ====================
339
+
152
340
  /**
153
- * Update group system prompt
154
- * Unlike regular AgentBuilder, this updates the group's systemPrompt in groupConfig
341
+ * Update a specific agent's system prompt (systemRole)
155
342
  */
156
- async updatePrompt(args: UpdateGroupPromptParams): Promise<BuiltinServerRuntimeOutput> {
343
+ async updateAgentPrompt(
344
+ groupId: string,
345
+ args: UpdateAgentPromptParams,
346
+ ): Promise<BuiltinServerRuntimeOutput> {
157
347
  try {
158
- const state = getChatGroupStoreState();
159
- const group = agentGroupSelectors.currentGroup(state);
348
+ const { agentId, prompt } = args;
160
349
 
161
- if (!group) {
162
- return {
163
- content: 'No active group found',
164
- error: 'No active group found',
165
- success: false,
166
- };
167
- }
350
+ // Get previous prompt for state
351
+ const state = getChatGroupStoreState();
352
+ const group = agentGroupSelectors.getGroupById(groupId)(state);
353
+ const agent = group?.agents?.find((a) => a.id === agentId);
354
+ const previousPrompt = agent?.systemRole ?? undefined;
168
355
 
169
- const previousPrompt = group.config?.systemPrompt;
356
+ // Update the agent's systemRole via agent store
357
+ await useAgentStore.getState().updateAgentConfigById(agentId, { systemRole: prompt });
170
358
 
171
- if (args.streaming) {
172
- // Use streaming mode for typewriter effect
173
- await this.streamUpdatePrompt(args.prompt);
174
- } else {
175
- // Update the system prompt directly
176
- await state.updateGroupConfig({ systemPrompt: args.prompt });
177
- }
359
+ // Refresh the group detail in the store to sync agent data
360
+ await state.refreshGroupDetail(groupId);
178
361
 
179
- const content = args.prompt
180
- ? `Successfully updated group system prompt (${args.prompt.length} characters)`
181
- : 'Successfully cleared group system prompt';
362
+ const content = prompt
363
+ ? `Successfully updated agent ${agentId} system prompt (${prompt.length} characters)`
364
+ : `Successfully cleared agent ${agentId} system prompt`;
182
365
 
183
366
  return {
184
367
  content,
185
368
  state: {
186
- newPrompt: args.prompt,
369
+ agentId,
370
+ newPrompt: prompt,
187
371
  previousPrompt,
188
372
  success: true,
189
- } as UpdateGroupPromptState,
373
+ },
190
374
  success: true,
191
375
  };
192
376
  } catch (error) {
193
377
  const err = error as Error;
194
378
  return {
195
- content: `Failed to update group prompt: ${err.message}`,
379
+ content: `Failed to update agent prompt: ${err.message}`,
196
380
  error,
197
- state: {
198
- newPrompt: args.prompt,
199
- success: false,
200
- } as UpdateGroupPromptState,
201
381
  success: false,
202
382
  };
203
383
  }
204
384
  }
205
385
 
206
386
  /**
207
- * Update group configuration (openingMessage, openingQuestions)
387
+ * Update group configuration and metadata (unified method)
208
388
  */
209
- async updateGroupConfig(args: UpdateGroupConfigParams): Promise<BuiltinServerRuntimeOutput> {
389
+ async updateGroup(args: UpdateGroupParams): Promise<BuiltinServerRuntimeOutput> {
210
390
  try {
211
391
  const state = getChatGroupStoreState();
212
392
  const group = agentGroupSelectors.currentGroup(state);
@@ -219,91 +399,155 @@ export class GroupAgentBuilderExecutionRuntime {
219
399
  };
220
400
  }
221
401
 
222
- const { config } = args;
402
+ const { config, meta } = args;
223
403
 
224
- if (!config) {
404
+ if (!config && !meta) {
225
405
  return {
226
- content: 'No configuration provided',
227
- error: 'No configuration provided',
406
+ content: 'No configuration or metadata provided',
407
+ error: 'No configuration or metadata provided',
228
408
  success: false,
229
409
  };
230
410
  }
231
411
 
232
- // Build the config update object
233
- const configUpdate: { openingMessage?: string; openingQuestions?: string[] } = {};
234
-
235
- if (config.openingMessage !== undefined) {
236
- configUpdate.openingMessage = config.openingMessage;
412
+ const updatedFields: string[] = [];
413
+ const resultState: UpdateGroupState = { success: true };
414
+
415
+ // Update config if provided
416
+ if (config) {
417
+ const configUpdate: { openingMessage?: string; openingQuestions?: string[] } = {};
418
+
419
+ if (config.openingMessage !== undefined) {
420
+ configUpdate.openingMessage = config.openingMessage;
421
+ updatedFields.push(
422
+ config.openingMessage
423
+ ? `openingMessage (${config.openingMessage.length} chars)`
424
+ : 'openingMessage (cleared)',
425
+ );
426
+ }
427
+
428
+ if (config.openingQuestions !== undefined) {
429
+ configUpdate.openingQuestions = config.openingQuestions;
430
+ updatedFields.push(
431
+ config.openingQuestions.length > 0
432
+ ? `openingQuestions (${config.openingQuestions.length} questions)`
433
+ : 'openingQuestions (cleared)',
434
+ );
435
+ }
436
+
437
+ if (Object.keys(configUpdate).length > 0) {
438
+ await state.updateGroupConfig(configUpdate);
439
+ resultState.updatedConfig = configUpdate;
440
+ }
237
441
  }
238
442
 
239
- if (config.openingQuestions !== undefined) {
240
- configUpdate.openingQuestions = config.openingQuestions;
443
+ // Update meta if provided
444
+ if (meta && Object.keys(meta).length > 0) {
445
+ await state.updateGroupMeta(meta);
446
+ resultState.updatedMeta = meta;
447
+
448
+ if (meta.avatar !== undefined) {
449
+ updatedFields.push(`avatar (${meta.avatar || 'cleared'})`);
450
+ }
451
+ if (meta.title !== undefined) {
452
+ updatedFields.push(`title (${meta.title || 'cleared'})`);
453
+ }
454
+ if (meta.description !== undefined) {
455
+ updatedFields.push(
456
+ meta.description
457
+ ? `description (${meta.description.length} chars)`
458
+ : 'description (cleared)',
459
+ );
460
+ }
461
+ if (meta.backgroundColor !== undefined) {
462
+ updatedFields.push(`backgroundColor (${meta.backgroundColor || 'cleared'})`);
463
+ }
241
464
  }
242
465
 
243
- // Update the group config
244
- await state.updateGroupConfig(configUpdate);
466
+ // Refresh the group detail in the store to ensure data sync
467
+ await state.refreshGroupDetail(group.id);
245
468
 
246
- const updatedFields: string[] = [];
247
- if (config.openingMessage !== undefined) {
248
- updatedFields.push(
249
- config.openingMessage
250
- ? `openingMessage (${config.openingMessage.length} chars)`
251
- : 'openingMessage (cleared)',
252
- );
469
+ const content = `Successfully updated group: ${updatedFields.join(', ')}`;
470
+
471
+ return {
472
+ content,
473
+ state: resultState,
474
+ success: true,
475
+ };
476
+ } catch (error) {
477
+ const err = error as Error;
478
+ return {
479
+ content: `Failed to update group: ${err.message}`,
480
+ error,
481
+ success: false,
482
+ };
483
+ }
484
+ }
485
+
486
+ /**
487
+ * Update group shared prompt/content
488
+ */
489
+ async updateGroupPrompt(args: UpdateGroupPromptParams): Promise<BuiltinServerRuntimeOutput> {
490
+ try {
491
+ const state = getChatGroupStoreState();
492
+ const group = agentGroupSelectors.currentGroup(state);
493
+
494
+ if (!group) {
495
+ return {
496
+ content: 'No active group found',
497
+ error: 'No active group found',
498
+ success: false,
499
+ };
253
500
  }
254
- if (config.openingQuestions !== undefined) {
255
- updatedFields.push(
256
- config.openingQuestions.length > 0
257
- ? `openingQuestions (${config.openingQuestions.length} questions)`
258
- : 'openingQuestions (cleared)',
259
- );
501
+
502
+ const previousPrompt = group.content ?? undefined;
503
+
504
+ if (args.streaming) {
505
+ // Use streaming mode for typewriter effect
506
+ await this.streamUpdateGroupPrompt(args.prompt);
507
+ } else {
508
+ // Update the content directly
509
+ await state.updateGroup(group.id, { content: args.prompt });
260
510
  }
261
511
 
262
- const content = `Successfully updated group configuration: ${updatedFields.join(', ')}`;
512
+ // Refresh the group detail in the store to ensure data sync
513
+ await state.refreshGroupDetail(group.id);
514
+
515
+ const content = args.prompt
516
+ ? `Successfully updated group shared prompt (${args.prompt.length} characters)`
517
+ : 'Successfully cleared group shared prompt';
263
518
 
264
519
  return {
265
520
  content,
266
521
  state: {
522
+ newPrompt: args.prompt,
523
+ previousPrompt,
267
524
  success: true,
268
- updatedConfig: configUpdate,
269
- } as UpdateGroupConfigState,
525
+ } as UpdateGroupPromptState,
270
526
  success: true,
271
527
  };
272
528
  } catch (error) {
273
529
  const err = error as Error;
274
530
  return {
275
- content: `Failed to update group configuration: ${err.message}`,
531
+ content: `Failed to update group prompt: ${err.message}`,
276
532
  error,
533
+ state: {
534
+ newPrompt: args.prompt,
535
+ success: false,
536
+ } as UpdateGroupPromptState,
277
537
  success: false,
278
538
  };
279
539
  }
280
540
  }
281
541
 
282
542
  /**
283
- * Stream update prompt with typewriter effect for group
543
+ * Stream update group prompt with typewriter effect
284
544
  */
285
- private async streamUpdatePrompt(prompt: string): Promise<void> {
545
+ private async streamUpdateGroupPrompt(prompt: string): Promise<void> {
286
546
  const state = getChatGroupStoreState();
547
+ const group = agentGroupSelectors.currentGroup(state);
287
548
 
288
- // Start streaming
289
- state.startStreamingSystemPrompt();
290
-
291
- // Simulate streaming by chunking the content
292
- const chunkSize = 5; // Characters per chunk
293
- const delay = 10; // Milliseconds between chunks
294
-
295
- for (let i = 0; i < prompt.length; i += chunkSize) {
296
- const chunk = prompt.slice(i, i + chunkSize);
297
- getChatGroupStoreState().appendStreamingSystemPrompt(chunk);
298
-
299
- // Small delay for typewriter effect
300
- if (i + chunkSize < prompt.length) {
301
- // eslint-disable-next-line no-promise-executor-return
302
- await new Promise((resolve) => setTimeout(resolve, delay));
303
- }
304
- }
549
+ if (!group) return;
305
550
 
306
- // Finish streaming - EditorCanvas will handle save when streaming ends
307
- await getChatGroupStoreState().finishStreamingSystemPrompt();
551
+ await state.updateGroup(group.id, { content: prompt });
308
552
  }
309
553
  }
@@ -0,0 +1,110 @@
1
+ 'use client';
2
+
3
+ import type { BuiltinInspectorProps } from '@lobechat/types';
4
+ import { Avatar, Flexbox } from '@lobehub/ui';
5
+ import { createStaticStyles, cssVar, cx } from 'antd-style';
6
+ import { Check } from 'lucide-react';
7
+ import { memo, useMemo } from 'react';
8
+ import { useTranslation } from 'react-i18next';
9
+
10
+ import { shinyTextStyles } from '@/styles';
11
+
12
+ import type { BatchCreateAgentsParams, BatchCreateAgentsState } from '../../../types';
13
+
14
+ const styles = createStaticStyles(({ css, cssVar: cv }) => ({
15
+ avatarGroup: css`
16
+ display: flex;
17
+ gap: 2px;
18
+ align-items: center;
19
+ `,
20
+ count: css`
21
+ color: ${cv.colorTextSecondary};
22
+ font-size: 12px;
23
+ `,
24
+ root: css`
25
+ overflow: hidden;
26
+ display: flex;
27
+ gap: 8px;
28
+ align-items: center;
29
+ `,
30
+ statusIcon: css`
31
+ flex-shrink: 0;
32
+ margin-block-end: -2px;
33
+ `,
34
+ title: css`
35
+ flex-shrink: 0;
36
+ color: ${cv.colorTextSecondary};
37
+ white-space: nowrap;
38
+ `,
39
+ }));
40
+
41
+ export const BatchCreateAgentsInspector = memo<
42
+ BuiltinInspectorProps<BatchCreateAgentsParams, BatchCreateAgentsState>
43
+ >(({ args, partialArgs, isArgumentsStreaming, isLoading, pluginState }) => {
44
+ const { t } = useTranslation('plugin');
45
+
46
+ const agents = args?.agents || partialArgs?.agents;
47
+
48
+ // Get display info from agents
49
+ const displayInfo = useMemo(() => {
50
+ if (!agents || agents.length === 0) return null;
51
+
52
+ const count = agents.length;
53
+ const displayAgents = agents.slice(0, 3); // Show up to 3 avatars
54
+
55
+ return { count, displayAgents };
56
+ }, [agents]);
57
+
58
+ // Initial streaming state
59
+ if (isArgumentsStreaming && !displayInfo) {
60
+ return (
61
+ <div className={cx(styles.root, shinyTextStyles.shinyText)}>
62
+ <span>{t('builtins.lobe-group-agent-builder.apiName.batchCreateAgents')}</span>
63
+ </div>
64
+ );
65
+ }
66
+
67
+ const isSuccess = pluginState?.successCount === pluginState?.agents?.length;
68
+ const successCount = pluginState?.successCount ?? 0;
69
+ const totalCount = displayInfo?.count ?? 0;
70
+
71
+ return (
72
+ <Flexbox
73
+ align={'center'}
74
+ className={cx(styles.root, (isArgumentsStreaming || isLoading) && shinyTextStyles.shinyText)}
75
+ gap={8}
76
+ horizontal
77
+ >
78
+ <span className={styles.title}>
79
+ {t('builtins.lobe-group-agent-builder.apiName.batchCreateAgents')}:
80
+ </span>
81
+ {displayInfo && (
82
+ <>
83
+ <div className={styles.avatarGroup}>
84
+ {displayInfo.displayAgents.map((agent, index) => (
85
+ <Avatar
86
+ key={index}
87
+ avatar={agent.avatar}
88
+ shape={'square'}
89
+ size={20}
90
+ title={agent.title}
91
+ />
92
+ ))}
93
+ </div>
94
+ <span className={styles.count}>
95
+ {pluginState
96
+ ? `${successCount}/${totalCount}`
97
+ : `${totalCount} ${t('builtins.lobe-group-agent-builder.inspector.agents')}`}
98
+ </span>
99
+ </>
100
+ )}
101
+ {!isLoading && isSuccess && (
102
+ <Check className={styles.statusIcon} color={cssVar.colorSuccess} size={14} />
103
+ )}
104
+ </Flexbox>
105
+ );
106
+ });
107
+
108
+ BatchCreateAgentsInspector.displayName = 'BatchCreateAgentsInspector';
109
+
110
+ export default BatchCreateAgentsInspector;
@@ -0,0 +1,72 @@
1
+ 'use client';
2
+
3
+ import type { BuiltinInspectorProps } from '@lobechat/types';
4
+ import { Avatar, Flexbox } from '@lobehub/ui';
5
+ import { createStaticStyles, cssVar, cx } from 'antd-style';
6
+ import { Check } from 'lucide-react';
7
+ import { memo } from 'react';
8
+ import { useTranslation } from 'react-i18next';
9
+
10
+ import { shinyTextStyles } from '@/styles';
11
+
12
+ import type { CreateAgentParams, CreateAgentState } from '../../../types';
13
+
14
+ const styles = createStaticStyles(({ css, cssVar: cv }) => ({
15
+ root: css`
16
+ overflow: hidden;
17
+ display: flex;
18
+ gap: 8px;
19
+ align-items: center;
20
+ `,
21
+ statusIcon: css`
22
+ flex-shrink: 0;
23
+ margin-block-end: -2px;
24
+ `,
25
+ title: css`
26
+ flex-shrink: 0;
27
+ color: ${cv.colorTextSecondary};
28
+ white-space: nowrap;
29
+ `,
30
+ }));
31
+
32
+ export const CreateAgentInspector = memo<
33
+ BuiltinInspectorProps<CreateAgentParams, CreateAgentState>
34
+ >(({ args, partialArgs, isArgumentsStreaming, isLoading, pluginState }) => {
35
+ const { t } = useTranslation('plugin');
36
+
37
+ const title = args?.title || partialArgs?.title;
38
+ const avatar = args?.avatar || partialArgs?.avatar;
39
+
40
+ // Initial streaming state
41
+ if (isArgumentsStreaming && !title) {
42
+ return (
43
+ <div className={cx(styles.root, shinyTextStyles.shinyText)}>
44
+ <span>{t('builtins.lobe-group-agent-builder.apiName.createAgent')}</span>
45
+ </div>
46
+ );
47
+ }
48
+
49
+ const isSuccess = pluginState?.success;
50
+
51
+ return (
52
+ <Flexbox
53
+ align={'center'}
54
+ className={cx(styles.root, (isArgumentsStreaming || isLoading) && shinyTextStyles.shinyText)}
55
+ gap={8}
56
+ horizontal
57
+ >
58
+ <span className={styles.title}>
59
+ {t('builtins.lobe-group-agent-builder.apiName.createAgent')}:
60
+ </span>
61
+ {avatar && <Avatar avatar={avatar} shape={'square'} size={20} title={title || undefined} />}
62
+ {title && <span>{title}</span>}
63
+ {!isLoading && isSuccess && (
64
+ <Check className={styles.statusIcon} color={cssVar.colorSuccess} size={14} />
65
+ )}
66
+ </Flexbox>
67
+ );
68
+ });
69
+
70
+ CreateAgentInspector.displayName = 'CreateAgentInspector';
71
+
72
+ export default CreateAgentInspector;