@lobehub/lobehub 2.0.0-next.374 → 2.0.0-next.376

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 (118) hide show
  1. package/.github/workflows/claude-migration-support.yml +1 -1
  2. package/.github/workflows/revalidate-docs.yml +25 -0
  3. package/CHANGELOG.md +66 -0
  4. package/apps/desktop/src/main/controllers/LocalFileCtr.ts +7 -1
  5. package/apps/desktop/src/main/controllers/ShellCommandCtr.ts +23 -10
  6. package/apps/desktop/src/main/controllers/__tests__/LocalFileCtr.test.ts +261 -0
  7. package/apps/desktop/src/main/controllers/__tests__/ShellCommandCtr.test.ts +36 -0
  8. package/apps/desktop/src/main/core/infrastructure/BackendProxyProtocolManager.ts +2 -1
  9. package/changelog/v1.json +21 -0
  10. package/docs/development/database-schema.dbml +89 -0
  11. package/docs/self-hosting/advanced/auth/nextauth-to-betterauth.mdx +6 -0
  12. package/docs/self-hosting/advanced/auth/nextauth-to-betterauth.zh-CN.mdx +5 -0
  13. package/docs/usage/features/auth.mdx +54 -33
  14. package/docs/usage/features/auth.zh-CN.mdx +56 -33
  15. package/locales/en-US/chat.json +13 -13
  16. package/locales/en-US/common.json +24 -0
  17. package/locales/en-US/setting.json +19 -0
  18. package/locales/zh-CN/authError.json +2 -0
  19. package/locales/zh-CN/chat.json +14 -14
  20. package/locales/zh-CN/common.json +24 -0
  21. package/locales/zh-CN/setting.json +19 -0
  22. package/package.json +2 -1
  23. package/packages/builtin-tool-group-agent-builder/src/ExecutionRuntime/index.ts +31 -9
  24. package/packages/builtin-tool-group-agent-builder/src/client/Inspector/InviteAgent/index.tsx +28 -12
  25. package/packages/builtin-tool-group-agent-builder/src/client/Inspector/RemoveAgent/index.tsx +28 -12
  26. package/packages/builtin-tool-group-agent-builder/src/types.ts +8 -0
  27. package/packages/builtin-tool-local-system/src/client/Render/EditLocalFile/index.tsx +1 -11
  28. package/packages/builtin-tool-local-system/src/client/Render/ListFiles/index.tsx +6 -11
  29. package/packages/context-engine/src/engine/tools/ToolsEngine.ts +16 -10
  30. package/packages/context-engine/src/engine/tools/__tests__/ToolsEngine.test.ts +142 -0
  31. package/packages/context-engine/src/engine/tools/types.ts +6 -0
  32. package/packages/database/migrations/0074_add_fk_indexes_for_cascade_delete.sql +56 -0
  33. package/packages/database/migrations/meta/0074_snapshot.json +10901 -0
  34. package/packages/database/migrations/meta/_journal.json +7 -0
  35. package/packages/database/src/models/message.ts +84 -81
  36. package/packages/database/src/repositories/search/index.ts +330 -570
  37. package/packages/database/src/schemas/agent.ts +4 -0
  38. package/packages/database/src/schemas/chatGroup.ts +2 -0
  39. package/packages/database/src/schemas/file.ts +4 -0
  40. package/packages/database/src/schemas/generation.ts +1 -0
  41. package/packages/database/src/schemas/message.ts +16 -0
  42. package/packages/database/src/schemas/nextauth.ts +15 -8
  43. package/packages/database/src/schemas/oidc.ts +104 -68
  44. package/packages/database/src/schemas/rag.ts +4 -0
  45. package/packages/database/src/schemas/ragEvals.ts +97 -73
  46. package/packages/database/src/schemas/relations.ts +7 -0
  47. package/packages/database/src/schemas/session.ts +1 -0
  48. package/packages/database/src/schemas/topic.ts +8 -1
  49. package/packages/desktop-bridge/src/index.ts +17 -0
  50. package/scripts/_shared/checkDeprecatedAuth.js +26 -0
  51. package/src/app/(backend)/trpc/async/[trpc]/route.ts +2 -0
  52. package/src/app/(backend)/trpc/lambda/[trpc]/route.ts +2 -5
  53. package/src/app/(backend)/trpc/mobile/[trpc]/route.ts +2 -5
  54. package/src/app/(backend)/trpc/tools/[trpc]/route.ts +2 -0
  55. package/src/app/[variants]/(auth)/signup/[[...signup]]/useSignUp.tsx +7 -4
  56. package/src/app/[variants]/(main)/agent/features/Conversation/AgentWelcome/index.tsx +3 -23
  57. package/src/app/[variants]/(main)/group/features/Conversation/AgentWelcome/index.tsx +3 -23
  58. package/src/app/[variants]/(main)/resource/(home)/index.tsx +4 -1
  59. package/src/app/[variants]/(main)/resource/library/_layout/Header/LibraryHead.tsx +3 -0
  60. package/src/app/[variants]/(main)/resource/library/_layout/Header/index.tsx +2 -1
  61. package/src/app/[variants]/(main)/settings/storage/features/Advanced.tsx +19 -12
  62. package/src/app/[variants]/(main)/settings/storage/index.tsx +19 -1
  63. package/src/business/client/features/AccountDeletion/index.tsx +3 -0
  64. package/src/business/server/lambda-routers/accountDeletion.ts +3 -0
  65. package/src/components/DragUpload/index.tsx +1 -1
  66. package/src/config/routes/index.ts +9 -1
  67. package/src/features/CommandMenu/ContextCommands.tsx +10 -2
  68. package/src/features/CommandMenu/MainMenu.tsx +29 -22
  69. package/src/features/CommandMenu/SearchResults.tsx +19 -0
  70. package/src/features/CommandMenu/components/CommandInput.tsx +1 -0
  71. package/src/features/CommandMenu/index.tsx +25 -3
  72. package/src/features/CommandMenu/styles.ts +1 -0
  73. package/src/features/CommandMenu/useCommandMenu.ts +8 -2
  74. package/src/features/CommandMenu/utils/contextCommands.ts +17 -2
  75. package/src/features/CommandMenu/utils/queryParser.ts +1 -0
  76. package/src/features/Conversation/ChatItem/ChatItem.tsx +4 -7
  77. package/src/features/Conversation/ChatItem/style.ts +0 -3
  78. package/src/features/Conversation/ChatItem/type.ts +4 -1
  79. package/src/features/Conversation/Messages/Assistant/index.tsx +6 -2
  80. package/src/features/Conversation/Messages/AssistantGroup/index.tsx +8 -3
  81. package/src/features/Conversation/Messages/Supervisor/index.tsx +6 -2
  82. package/src/features/Conversation/Messages/Task/index.tsx +6 -2
  83. package/src/features/Conversation/Messages/components/useNewScreen.test.ts +331 -0
  84. package/src/features/Conversation/Messages/components/useNewScreen.ts +80 -5
  85. package/src/features/Electron/connection/Connection.tsx +20 -15
  86. package/src/features/FileViewer/index.tsx +28 -5
  87. package/src/features/ModelSwitchPanel/components/List/ListItemRenderer.tsx +10 -9
  88. package/src/features/ModelSwitchPanel/components/List/MultipleProvidersModelItem.tsx +1 -0
  89. package/src/features/ModelSwitchPanel/components/Toolbar.tsx +1 -1
  90. package/src/features/ResourceManager/components/Editor/index.tsx +7 -4
  91. package/src/features/ResourceManager/components/Explorer/Header/index.tsx +1 -1
  92. package/src/features/ResourceManager/components/Explorer/ItemDropdown/useFileItemDropdown.tsx +12 -1
  93. package/src/features/ResourceManager/components/Explorer/ListView/ListItem/index.tsx +23 -43
  94. package/src/features/ResourceManager/components/Explorer/MasonryView/MasonryFileItem/ImageFileItem.tsx +1 -0
  95. package/src/features/ResourceManager/components/Explorer/MasonryView/MasonryFileItem/index.tsx +24 -44
  96. package/src/features/ResourceManager/components/Explorer/hooks/useFileItemClick.ts +78 -0
  97. package/src/features/ResourceManager/components/Header/AddButton.tsx +0 -5
  98. package/src/features/ResourceManager/index.tsx +38 -24
  99. package/src/libs/better-auth/define-config.ts +17 -0
  100. package/src/libs/better-auth/plugins/email-whitelist.ts +4 -1
  101. package/src/libs/redis/manager.ts +5 -9
  102. package/src/libs/trpc/utils/responseMeta.test.ts +82 -0
  103. package/src/libs/trpc/utils/responseMeta.ts +41 -0
  104. package/src/locales/default/authError.ts +3 -0
  105. package/src/locales/default/chat.ts +13 -13
  106. package/src/locales/default/common.ts +82 -4
  107. package/src/locales/default/setting.ts +23 -1
  108. package/src/server/modules/AgentRuntime/redis.ts +3 -0
  109. package/src/server/routers/lambda/index.ts +2 -0
  110. package/src/server/routers/lambda/search.ts +3 -2
  111. package/src/services/chat/chat.test.ts +125 -45
  112. package/src/services/chat/index.ts +10 -14
  113. package/src/services/chat/mecha/agentConfigResolver.ts +8 -0
  114. package/src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts +29 -0
  115. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +27 -19
  116. package/src/utils/errorResponse.ts +2 -1
  117. package/src/app/[variants]/(main)/agent/features/Conversation/AgentWelcome/AddButton.tsx +0 -37
  118. package/src/app/[variants]/(main)/group/features/Conversation/AgentWelcome/AddButton.tsx +0 -32
@@ -1,6 +1,25 @@
1
1
  {
2
2
  "_cloud.officialProvider": "{{name}} Official Model Service",
3
3
  "about.title": "About",
4
+ "accountDeletion.cancelButton": "Cancel Deletion",
5
+ "accountDeletion.cancelConfirmTitle": "Cancel account deletion request?",
6
+ "accountDeletion.cancelFailed": "Failed to cancel deletion request",
7
+ "accountDeletion.cancelSuccess": "Deletion request cancelled",
8
+ "accountDeletion.confirmCheckbox": "I have read and understood the above, and confirm to proceed with account deletion",
9
+ "accountDeletion.confirmContent": "After submission, you will enter a <0>72-hour</0> cooling-off period during which you can cancel at any time. Once the period ends, your account data will be permanently deleted, unpaid invoices will be canceled immediately, and paid fees will not be refunded. Your registration and deletion records will be retained for compliance purposes.",
10
+ "accountDeletion.confirmOk": "Delete Account",
11
+ "accountDeletion.confirmRequired": "Please confirm you understand the consequences",
12
+ "accountDeletion.confirmTitle": "Delete Account?",
13
+ "accountDeletion.desc": "Permanently delete your account and all associated data. This action cannot be undone.",
14
+ "accountDeletion.pendingDesc": "Your account is scheduled for deletion",
15
+ "accountDeletion.pendingMessage": "Your account will be deleted in {{hours}} hours",
16
+ "accountDeletion.reasonPlaceholder": "Please tell us why you want to delete your account...",
17
+ "accountDeletion.reasonRequired": "Please provide a reason for deletion",
18
+ "accountDeletion.requestButton": "Request Account Deletion",
19
+ "accountDeletion.requestFailed": "Failed to request account deletion",
20
+ "accountDeletion.requestSuccess": "Deletion request submitted",
21
+ "accountDeletion.sectionTitle": "Account Deletion",
22
+ "accountDeletion.title": "Delete Account",
4
23
  "advancedSettings": "Advanced Settings",
5
24
  "agentCronJobs.addJob": "Add Scheduled Task",
6
25
  "agentCronJobs.confirmDelete": "Are you sure you want to delete this scheduled task?",
@@ -5,7 +5,9 @@
5
5
  "codes.ACCOUNT_ALREADY_LINKED_TO_DIFFERENT_USER": "这个账号已绑定到其他用户,请使用其他方式登录",
6
6
  "codes.ACCOUNT_NOT_FOUND": "没有找到对应账号,请检查登录方式或注册新账号",
7
7
  "codes.CREDENTIAL_ACCOUNT_NOT_FOUND": "凭证账号不存在,请重新授权或联系支持",
8
+ "codes.DELETED_ACCOUNT_EMAIL": "该邮箱关联的账号已注销,无法再次注册",
8
9
  "codes.EMAIL_CAN_NOT_BE_UPDATED": "当前邮箱无法修改,如需更换,请联系支持",
10
+ "codes.EMAIL_NOT_ALLOWED": "该邮箱不允许注册",
9
11
  "codes.EMAIL_NOT_VERIFIED": "邮箱还未验证,请先查收验证邮件完成验证",
10
12
  "codes.FAILED_TO_CREATE_SESSION": "会话创建遇到了问题。你可以先重试;如仍失败,请检查网络或稍后再试",
11
13
  "codes.FAILED_TO_CREATE_USER": "创建用户遇到了问题。你可以稍后再试",
@@ -36,7 +36,7 @@
36
36
  "compression.summary": "摘要",
37
37
  "confirmClearCurrentMessages": "确认清空当前会话消息吗?清空后无法恢复",
38
38
  "confirmRemoveChatGroupItemAlert": "确认删除该群组吗?群组专有助理将会被同样删除,外部助理不受影响",
39
- "confirmRemoveGroupItemAlert": "确认删除该分组吗?分组内的助理会移回默认列表",
39
+ "confirmRemoveGroupItemAlert": "确认删除该分类吗?分类内的助理会移回默认列表",
40
40
  "confirmRemoveGroupSuccess": "群组已删除",
41
41
  "confirmRemoveSessionItemAlert": "确认删除该助理吗?删除后无法恢复",
42
42
  "confirmRemoveSessionSuccess": "助理已删除",
@@ -239,28 +239,28 @@
239
239
  "searchAgents": "搜索助理…",
240
240
  "selectedAgents": "已选助理",
241
241
  "sendPlaceholder": "从任何想法开始… <hotkey><hotkey/>",
242
- "sessionGroup.config": "分组管理",
243
- "sessionGroup.confirmRemoveGroupAlert": "确认删除该分组吗?分组内的助理会移回默认列表",
242
+ "sessionGroup.config": "分类管理",
243
+ "sessionGroup.confirmRemoveGroupAlert": "确认删除该分类吗?分类内的助理会移回默认列表",
244
244
  "sessionGroup.createAgentSuccess": "助理创建成功",
245
- "sessionGroup.createGroup": "添加新分组",
246
- "sessionGroup.createGroupFailed": "群组创建失败",
247
- "sessionGroup.createGroupSuccess": "群组创建成功",
248
- "sessionGroup.createSuccess": "分组创建成功",
245
+ "sessionGroup.createGroup": "添加新分类",
246
+ "sessionGroup.createGroupFailed": "分类创建失败",
247
+ "sessionGroup.createGroupSuccess": "分类创建成功",
248
+ "sessionGroup.createSuccess": "分类创建成功",
249
249
  "sessionGroup.creatingAgent": "正在创建助理…",
250
- "sessionGroup.groupName": "分组名称",
251
- "sessionGroup.inputPlaceholder": "请输入分组名称…",
252
- "sessionGroup.moveGroup": "移动到分组",
253
- "sessionGroup.newGroup": "新分组",
250
+ "sessionGroup.groupName": "分类名称",
251
+ "sessionGroup.inputPlaceholder": "请输入分类名称…",
252
+ "sessionGroup.moveGroup": "移动到分类",
253
+ "sessionGroup.newGroup": "新分类",
254
254
  "sessionGroup.noAvailableAgents": "暂无可用助理",
255
255
  "sessionGroup.noMatchingAgents": "未找到匹配的助理",
256
256
  "sessionGroup.noSelectedAgents": "请选择助理",
257
- "sessionGroup.rename": "重命名分组",
257
+ "sessionGroup.rename": "重命名分类",
258
258
  "sessionGroup.renameSuccess": "重命名成功",
259
259
  "sessionGroup.searchAgents": "搜索助理",
260
260
  "sessionGroup.selectedAgents": "已选助理({{count}})",
261
261
  "sessionGroup.sortSuccess": "排序已更新",
262
- "sessionGroup.sorting": "正在更新排序…",
263
- "sessionGroup.tooLong": "分组名称长度需为 1–20 个字符",
262
+ "sessionGroup.sorting": "正在更新分类排序…",
263
+ "sessionGroup.tooLong": "分类名称长度需为 1–20 个字符",
264
264
  "shareModal.copy": "复制",
265
265
  "shareModal.copyLink": "复制链接",
266
266
  "shareModal.copyLinkSuccess": "链接已复制",
@@ -165,6 +165,30 @@
165
165
  "cmdk.themeLight": "浅色模式",
166
166
  "cmdk.toOpen": "打开",
167
167
  "cmdk.toSelect": "选择",
168
+ "cmdk.keywords.contactUs": "反馈 问题 错误 建议 联系",
169
+ "cmdk.keywords.submitIssue": "问题 错误 反馈 建议 提交",
170
+ "cmdk.keywords.starGitHub": "github star 收藏 喜欢 点赞",
171
+ "cmdk.keywords.discord": "discord 帮助 支持 客服 社区",
172
+ "cmdk.keywords.community": "发现 市场 助理 模型 提供商 mcp",
173
+ "cmdk.keywords.painting": "绘画 艺术 生成 画图 绘图",
174
+ "cmdk.keywords.resources": "知识 文件 库 文档 资源",
175
+ "cmdk.keywords.pages": "文档 写作 笔记 文稿",
176
+ "cmdk.keywords.memory": "身份 上下文 偏好 经验 记忆",
177
+ "cmdk.keywords.settings": "设置 偏好 配置 选项",
178
+ "cmdk.keywords.profile": "个人资料 用户 账户 账号",
179
+ "cmdk.keywords.appearance": "通用 外观 主题 显示",
180
+ "cmdk.keywords.provider": "提供商 llm 模型 ai 大模型",
181
+ "cmdk.keywords.hotkey": "热键 快捷键 键盘",
182
+ "cmdk.keywords.image": "图像 图片 照片",
183
+ "cmdk.keywords.proxy": "代理 网络 连接",
184
+ "cmdk.keywords.stats": "统计 数据 分析",
185
+ "cmdk.keywords.apikey": "apikey api 密钥 令牌",
186
+ "cmdk.keywords.about": "关于 版本 信息",
187
+ "cmdk.keywords.plans": "订阅 计划 升级 定价 会员",
188
+ "cmdk.keywords.funds": "资金 余额 积分 充值",
189
+ "cmdk.keywords.usage": "用量 统计 消耗 配额",
190
+ "cmdk.keywords.billing": "账单 支付 发票 交易",
191
+ "cmdk.keywords.referral": "推荐 奖励 邀请 返利",
168
192
  "confirm": "确认",
169
193
  "contact": "联系我们",
170
194
  "copy": "复制",
@@ -1,6 +1,25 @@
1
1
  {
2
2
  "_cloud.officialProvider": "{{name}} 官方模型服务",
3
3
  "about.title": "关于",
4
+ "accountDeletion.cancelButton": "取消注销",
5
+ "accountDeletion.cancelConfirmTitle": "取消账号注销请求?",
6
+ "accountDeletion.cancelFailed": "取消注销请求失败",
7
+ "accountDeletion.cancelSuccess": "注销请求已取消",
8
+ "accountDeletion.confirmCheckbox": "我已阅读并理解上述内容,确认继续注销账号",
9
+ "accountDeletion.confirmContent": "提交后将进入 <0>72 小时</0>冷静期,期间您可以随时取消。冷静期结束后,您的账号数据将被永久删除,未支付的账单将立即取消,已支付的费用不予退还。您的注册及注销记录将被保留用于合规审计。",
10
+ "accountDeletion.confirmOk": "注销账号",
11
+ "accountDeletion.confirmRequired": "请确认您了解注销的后果",
12
+ "accountDeletion.confirmTitle": "确定要注销账号吗?",
13
+ "accountDeletion.desc": "永久删除您的账号及所有相关数据,此操作不可撤销。",
14
+ "accountDeletion.pendingDesc": "您的账号已被安排删除",
15
+ "accountDeletion.pendingMessage": "您的账号将于 {{hours}} 小时后删除",
16
+ "accountDeletion.reasonPlaceholder": "请告诉我们您为什么要注销账号...",
17
+ "accountDeletion.reasonRequired": "请填写注销原因",
18
+ "accountDeletion.requestButton": "申请注销账号",
19
+ "accountDeletion.requestFailed": "申请注销账号失败",
20
+ "accountDeletion.requestSuccess": "注销申请已提交",
21
+ "accountDeletion.sectionTitle": "账号注销",
22
+ "accountDeletion.title": "注销账号",
4
23
  "advancedSettings": "进阶配置",
5
24
  "agentCronJobs.addJob": "添加定时任务",
6
25
  "agentCronJobs.confirmDelete": "确定要删除此定时任务吗?",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.0.0-next.374",
3
+ "version": "2.0.0-next.376",
4
4
  "description": "LobeHub - an open-source,comprehensive AI Agent framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -342,6 +342,7 @@
342
342
  "tokenx": "^1.3.0",
343
343
  "ts-md5": "^2.0.1",
344
344
  "ua-parser-js": "^1.0.41",
345
+ "undici": "^7.19.1",
345
346
  "unist-builder": "^4.0.0",
346
347
  "url-join": "^5.0.0",
347
348
  "use-merge-value": "^1.2.0",
@@ -256,13 +256,15 @@ export class GroupAgentBuilderExecutionRuntime {
256
256
 
257
257
  // Check if agent is already in the group
258
258
  const existingAgents = group.agents || [];
259
- const isAlreadyInGroup = existingAgents.some((a) => a.id === args.agentId);
259
+ const existingAgent = existingAgents.find((a) => a.id === args.agentId);
260
260
 
261
- if (isAlreadyInGroup) {
261
+ if (existingAgent) {
262
262
  return {
263
- content: `Agent ${args.agentId} is already in the group`,
263
+ content: `Agent ${existingAgent.title || args.agentId} is already in the group`,
264
264
  state: {
265
+ agentAvatar: existingAgent.avatar,
265
266
  agentId: args.agentId,
267
+ agentName: existingAgent.title,
266
268
  success: false,
267
269
  } as InviteAgentState,
268
270
  success: false,
@@ -277,12 +279,22 @@ export class GroupAgentBuilderExecutionRuntime {
277
279
 
278
280
  const wasAdded = result.added.length > 0;
279
281
 
282
+ // Get the agent info from the updated group
283
+ const updatedGroup = agentGroupSelectors.getGroupById(groupId)(getChatGroupStoreState());
284
+ const addedAgent = updatedGroup?.agents?.find((a) => a.id === args.agentId);
285
+ const agentName = addedAgent?.title;
286
+ const agentAvatar = addedAgent?.avatar;
287
+
288
+ const agentDisplay = agentName ? `${agentName} (ID: ${args.agentId})` : args.agentId;
289
+
280
290
  return {
281
291
  content: wasAdded
282
- ? `Successfully invited agent ${args.agentId} to the group`
283
- : `Agent ${args.agentId} was already in the group`,
292
+ ? `Successfully invited agent ${agentDisplay} to the group`
293
+ : `Agent ${agentDisplay} was already in the group`,
284
294
  state: {
295
+ agentAvatar,
285
296
  agentId: args.agentId,
297
+ agentName,
286
298
  success: wasAdded,
287
299
  } as InviteAgentState,
288
300
  success: wasAdded,
@@ -315,9 +327,9 @@ export class GroupAgentBuilderExecutionRuntime {
315
327
 
316
328
  // Check if agent is in the group
317
329
  const existingAgents = group.agents || [];
318
- const isInGroup = existingAgents.some((a) => a.id === args.agentId);
330
+ const agent = existingAgents.find((a) => a.id === args.agentId);
319
331
 
320
- if (!isInGroup) {
332
+ if (!agent) {
321
333
  return {
322
334
  content: `Agent ${args.agentId} is not in the group`,
323
335
  state: {
@@ -328,12 +340,20 @@ export class GroupAgentBuilderExecutionRuntime {
328
340
  };
329
341
  }
330
342
 
343
+ // Get agent info before removing
344
+ const agentName = agent.title;
345
+ const agentAvatar = agent.avatar;
346
+
347
+ const agentDisplay = agentName ? `${agentName} (ID: ${args.agentId})` : args.agentId;
348
+
331
349
  // Check if this is the supervisor agent (cannot be removed)
332
350
  if (group.supervisorAgentId === args.agentId) {
333
351
  return {
334
- content: `Cannot remove supervisor agent ${args.agentId} from the group`,
352
+ content: `Cannot remove supervisor agent ${agentDisplay} from the group`,
335
353
  state: {
354
+ agentAvatar,
336
355
  agentId: args.agentId,
356
+ agentName,
337
357
  success: false,
338
358
  } as RemoveAgentState,
339
359
  success: false,
@@ -347,9 +367,11 @@ export class GroupAgentBuilderExecutionRuntime {
347
367
  await state.refreshGroupDetail(groupId);
348
368
 
349
369
  return {
350
- content: `Successfully removed agent ${args.agentId} from the group`,
370
+ content: `Successfully removed agent ${agentDisplay} from the group`,
351
371
  state: {
372
+ agentAvatar,
352
373
  agentId: args.agentId,
374
+ agentName,
353
375
  success: true,
354
376
  } as RemoveAgentState,
355
377
  success: true,
@@ -1,19 +1,31 @@
1
1
  'use client';
2
2
 
3
3
  import type { BuiltinInspectorProps } from '@lobechat/types';
4
+ import { Avatar, Flexbox } from '@lobehub/ui';
4
5
  import { createStaticStyles, cssVar, cx } from 'antd-style';
5
6
  import { Check } from 'lucide-react';
6
7
  import { memo } from 'react';
7
8
  import { useTranslation } from 'react-i18next';
8
9
 
9
- import { highlightTextStyles, inspectorTextStyles, shinyTextStyles } from '@/styles';
10
+ import { shinyTextStyles } from '@/styles';
10
11
 
11
12
  import type { InviteAgentParams, InviteAgentState } from '../../../types';
12
13
 
13
- const styles = createStaticStyles(({ css }) => ({
14
+ const styles = createStaticStyles(({ css, cssVar: cv }) => ({
15
+ root: css`
16
+ overflow: hidden;
17
+ display: flex;
18
+ gap: 8px;
19
+ align-items: center;
20
+ `,
14
21
  statusIcon: css`
22
+ flex-shrink: 0;
15
23
  margin-block-end: -2px;
16
- margin-inline-start: 4px;
24
+ `,
25
+ title: css`
26
+ flex-shrink: 0;
27
+ color: ${cv.colorTextSecondary};
28
+ white-space: nowrap;
17
29
  `,
18
30
  }));
19
31
 
@@ -24,11 +36,12 @@ export const InviteAgentInspector = memo<
24
36
 
25
37
  const agentId = args?.agentId || partialArgs?.agentId;
26
38
  const displayName = pluginState?.agentName || agentId;
39
+ const avatar = pluginState?.agentAvatar;
27
40
 
28
41
  // Initial streaming state
29
42
  if (isArgumentsStreaming && !agentId) {
30
43
  return (
31
- <div className={cx(inspectorTextStyles.root, shinyTextStyles.shinyText)}>
44
+ <div className={cx(styles.root, shinyTextStyles.shinyText)}>
32
45
  <span>{t('builtins.lobe-group-agent-builder.apiName.inviteAgent')}</span>
33
46
  </div>
34
47
  );
@@ -37,18 +50,21 @@ export const InviteAgentInspector = memo<
37
50
  const isSuccess = pluginState?.success;
38
51
 
39
52
  return (
40
- <div
41
- className={cx(
42
- inspectorTextStyles.root,
43
- (isArgumentsStreaming || isLoading) && shinyTextStyles.shinyText,
44
- )}
53
+ <Flexbox
54
+ align={'center'}
55
+ className={cx(styles.root, (isArgumentsStreaming || isLoading) && shinyTextStyles.shinyText)}
56
+ gap={8}
57
+ horizontal
45
58
  >
46
- <span>{t('builtins.lobe-group-agent-builder.apiName.inviteAgent')}: </span>
47
- {displayName && <span className={highlightTextStyles.primary}>{displayName}</span>}
59
+ <span className={styles.title}>
60
+ {t('builtins.lobe-group-agent-builder.apiName.inviteAgent')}:
61
+ </span>
62
+ {avatar && <Avatar avatar={avatar} shape={'square'} size={20} title={displayName || undefined} />}
63
+ {displayName && <span>{displayName}</span>}
48
64
  {!isLoading && isSuccess && (
49
65
  <Check className={styles.statusIcon} color={cssVar.colorSuccess} size={14} />
50
66
  )}
51
- </div>
67
+ </Flexbox>
52
68
  );
53
69
  });
54
70
 
@@ -1,19 +1,31 @@
1
1
  'use client';
2
2
 
3
3
  import type { BuiltinInspectorProps } from '@lobechat/types';
4
+ import { Avatar, Flexbox } from '@lobehub/ui';
4
5
  import { createStaticStyles, cssVar, cx } from 'antd-style';
5
6
  import { Check } from 'lucide-react';
6
7
  import { memo } from 'react';
7
8
  import { useTranslation } from 'react-i18next';
8
9
 
9
- import { highlightTextStyles, inspectorTextStyles, shinyTextStyles } from '@/styles';
10
+ import { shinyTextStyles } from '@/styles';
10
11
 
11
12
  import type { RemoveAgentParams, RemoveAgentState } from '../../../types';
12
13
 
13
- const styles = createStaticStyles(({ css }) => ({
14
+ const styles = createStaticStyles(({ css, cssVar: cv }) => ({
15
+ root: css`
16
+ overflow: hidden;
17
+ display: flex;
18
+ gap: 8px;
19
+ align-items: center;
20
+ `,
14
21
  statusIcon: css`
22
+ flex-shrink: 0;
15
23
  margin-block-end: -2px;
16
- margin-inline-start: 4px;
24
+ `,
25
+ title: css`
26
+ flex-shrink: 0;
27
+ color: ${cv.colorTextSecondary};
28
+ white-space: nowrap;
17
29
  `,
18
30
  }));
19
31
 
@@ -24,11 +36,12 @@ export const RemoveAgentInspector = memo<
24
36
 
25
37
  const agentId = args?.agentId || partialArgs?.agentId;
26
38
  const displayName = pluginState?.agentName || agentId;
39
+ const avatar = pluginState?.agentAvatar;
27
40
 
28
41
  // Initial streaming state
29
42
  if (isArgumentsStreaming && !agentId) {
30
43
  return (
31
- <div className={cx(inspectorTextStyles.root, shinyTextStyles.shinyText)}>
44
+ <div className={cx(styles.root, shinyTextStyles.shinyText)}>
32
45
  <span>{t('builtins.lobe-group-agent-builder.apiName.removeAgent')}</span>
33
46
  </div>
34
47
  );
@@ -37,18 +50,21 @@ export const RemoveAgentInspector = memo<
37
50
  const isSuccess = pluginState?.success;
38
51
 
39
52
  return (
40
- <div
41
- className={cx(
42
- inspectorTextStyles.root,
43
- (isArgumentsStreaming || isLoading) && shinyTextStyles.shinyText,
44
- )}
53
+ <Flexbox
54
+ align={'center'}
55
+ className={cx(styles.root, (isArgumentsStreaming || isLoading) && shinyTextStyles.shinyText)}
56
+ gap={8}
57
+ horizontal
45
58
  >
46
- <span>{t('builtins.lobe-group-agent-builder.apiName.removeAgent')}: </span>
47
- {displayName && <span className={highlightTextStyles.primary}>{displayName}</span>}
59
+ <span className={styles.title}>
60
+ {t('builtins.lobe-group-agent-builder.apiName.removeAgent')}:
61
+ </span>
62
+ {avatar && <Avatar avatar={avatar} shape={'square'} size={20} title={displayName || undefined} />}
63
+ {displayName && <span>{displayName}</span>}
48
64
  {!isLoading && isSuccess && (
49
65
  <Check className={styles.statusIcon} color={cssVar.colorSuccess} size={14} />
50
66
  )}
51
- </div>
67
+ </Flexbox>
52
68
  );
53
69
  });
54
70
 
@@ -265,6 +265,10 @@ export interface CreateAgentState {
265
265
  }
266
266
 
267
267
  export interface InviteAgentState {
268
+ /**
269
+ * Agent avatar (emoji or URL)
270
+ */
271
+ agentAvatar?: string;
268
272
  /**
269
273
  * Agent identifier that was invited
270
274
  */
@@ -280,6 +284,10 @@ export interface InviteAgentState {
280
284
  }
281
285
 
282
286
  export interface RemoveAgentState {
287
+ /**
288
+ * Agent avatar (emoji or URL)
289
+ */
290
+ agentAvatar?: string;
283
291
  /**
284
292
  * Agent identifier that was removed
285
293
  */
@@ -1,21 +1,16 @@
1
1
  import { type EditLocalFileState } from '@lobechat/builtin-tool-local-system';
2
2
  import { type EditLocalFileParams } from '@lobechat/electron-client-ipc';
3
3
  import { type BuiltinRenderProps } from '@lobechat/types';
4
- import { Alert, Flexbox, Icon, Skeleton } from '@lobehub/ui';
5
- import { ChevronRight } from 'lucide-react';
4
+ import { Alert, Flexbox, Skeleton } from '@lobehub/ui';
6
5
  import { useTheme } from 'next-themes';
7
- import path from 'path-browserify-esm';
8
6
  import React, { memo, useMemo } from 'react';
9
7
  import { Diff, Hunk, parseDiff } from 'react-diff-view';
10
8
  import 'react-diff-view/style/index.css';
11
9
 
12
- import { LocalFile, LocalFolder } from '@/features/LocalFile';
13
10
  import '@/styles/react-diff-view.dark.css';
14
11
 
15
12
  const EditLocalFile = memo<BuiltinRenderProps<EditLocalFileParams, EditLocalFileState>>(
16
13
  ({ args, pluginState, pluginError }) => {
17
- const { base, dir } = path.parse(args.file_path);
18
-
19
14
  // Parse diff for react-diff-view
20
15
  const files = useMemo(() => {
21
16
  const diffText = pluginState?.diffText;
@@ -35,11 +30,6 @@ const EditLocalFile = memo<BuiltinRenderProps<EditLocalFileParams, EditLocalFile
35
30
 
36
31
  return (
37
32
  <Flexbox gap={12}>
38
- <Flexbox horizontal>
39
- <LocalFolder path={dir} />
40
- <Icon icon={ChevronRight} />
41
- <LocalFile name={base} path={args.file_path} />
42
- </Flexbox>
43
33
  {pluginError ? (
44
34
  <Alert
45
35
  description={pluginError.message || 'Unknown error occurred'}
@@ -3,21 +3,16 @@ import { type ListLocalFileParams } from '@lobechat/electron-client-ipc';
3
3
  import { type BuiltinRenderProps } from '@lobechat/types';
4
4
  import React, { memo } from 'react';
5
5
 
6
- import { LocalFolder } from '@/features/LocalFile';
7
-
8
6
  import SearchResult from './Result';
9
7
 
10
8
  const ListFiles = memo<BuiltinRenderProps<ListLocalFileParams, LocalFileListState>>(
11
- ({ messageId, pluginError, args, pluginState }) => {
9
+ ({ messageId, pluginError, pluginState }) => {
12
10
  return (
13
- <>
14
- <LocalFolder path={args.path} />
15
- <SearchResult
16
- listResults={pluginState?.listResults}
17
- messageId={messageId}
18
- pluginError={pluginError}
19
- />
20
- </>
11
+ <SearchResult
12
+ listResults={pluginState?.listResults}
13
+ messageId={messageId}
14
+ pluginError={pluginError}
15
+ />
21
16
  );
22
17
  },
23
18
  );
@@ -53,17 +53,20 @@ export class ToolsEngine {
53
53
  * @returns Processed tools array, or undefined if tools should not be enabled
54
54
  */
55
55
  generateTools(params: GenerateToolsParams): UniformTool[] | undefined {
56
- const { toolIds = [], model, provider, context } = params;
56
+ const { toolIds = [], model, provider, context, skipDefaultTools } = params;
57
57
 
58
- // Merge user-provided tool IDs with default tool IDs
59
- const allToolIds = [...new Set([...toolIds, ...this.defaultToolIds])];
58
+ // Merge user-provided tool IDs with default tool IDs (unless skipDefaultTools is true)
59
+ const allToolIds = skipDefaultTools
60
+ ? toolIds
61
+ : [...new Set([...toolIds, ...this.defaultToolIds])];
60
62
 
61
63
  log(
62
- 'Generating tools for model=%s, provider=%s, pluginIds=%o (includes %d default tools)',
64
+ 'Generating tools for model=%s, provider=%s, pluginIds=%o (skipDefaultTools=%s, includes %d default tools)',
63
65
  model,
64
66
  provider,
65
67
  allToolIds,
66
- this.defaultToolIds.length,
68
+ skipDefaultTools,
69
+ skipDefaultTools ? 0 : this.defaultToolIds.length,
67
70
  );
68
71
 
69
72
  // 1. Check if model supports Function Calling
@@ -94,17 +97,20 @@ export class ToolsEngine {
94
97
  * @returns Detailed tools generation result
95
98
  */
96
99
  generateToolsDetailed(params: GenerateToolsParams): ToolsGenerationResult {
97
- const { toolIds = [], model, provider, context } = params;
100
+ const { toolIds = [], model, provider, context, skipDefaultTools } = params;
98
101
 
99
- // Merge user-provided tool IDs with default tool IDs and deduplicate
100
- const allToolIds = [...new Set([...toolIds, ...this.defaultToolIds])];
102
+ // Merge user-provided tool IDs with default tool IDs and deduplicate (unless skipDefaultTools is true)
103
+ const allToolIds = skipDefaultTools
104
+ ? toolIds
105
+ : [...new Set([...toolIds, ...this.defaultToolIds])];
101
106
 
102
107
  log(
103
- 'Generating detailed tools for model=%s, provider=%s, pluginIds=%o (includes %d default tools)',
108
+ 'Generating detailed tools for model=%s, provider=%s, pluginIds=%o (skipDefaultTools=%s, includes %d default tools)',
104
109
  model,
105
110
  provider,
106
111
  allToolIds,
107
- this.defaultToolIds.length,
112
+ skipDefaultTools,
113
+ skipDefaultTools ? 0 : this.defaultToolIds.length,
108
114
  );
109
115
 
110
116
  // Check if model supports Function Calling