@lobehub/lobehub 2.0.0-next.272 → 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.
- package/CHANGELOG.md +59 -0
- package/changelog/v1.json +18 -0
- package/locales/ar/chat.json +7 -0
- package/locales/ar/common.json +1 -1
- package/locales/ar/discover.json +2 -2
- package/locales/ar/models.json +40 -12
- package/locales/ar/onboarding.json +1 -1
- package/locales/ar/plugin.json +22 -1
- package/locales/ar/providers.json +0 -1
- package/locales/bg-BG/chat.json +7 -0
- package/locales/bg-BG/common.json +2 -0
- package/locales/bg-BG/discover.json +2 -2
- package/locales/bg-BG/models.json +48 -13
- package/locales/bg-BG/onboarding.json +1 -1
- package/locales/bg-BG/plugin.json +22 -1
- package/locales/bg-BG/providers.json +0 -1
- package/locales/de-DE/chat.json +7 -0
- package/locales/de-DE/common.json +2 -0
- package/locales/de-DE/discover.json +2 -2
- package/locales/de-DE/models.json +37 -13
- package/locales/de-DE/onboarding.json +3 -0
- package/locales/de-DE/plugin.json +22 -1
- package/locales/de-DE/providers.json +0 -1
- package/locales/en-US/chat.json +7 -0
- package/locales/en-US/discover.json +2 -2
- package/locales/en-US/models.json +15 -15
- package/locales/en-US/plugin.json +22 -1
- package/locales/en-US/providers.json +0 -1
- package/locales/es-ES/chat.json +7 -0
- package/locales/es-ES/common.json +2 -0
- package/locales/es-ES/discover.json +2 -2
- package/locales/es-ES/models.json +32 -14
- package/locales/es-ES/onboarding.json +3 -0
- package/locales/es-ES/plugin.json +22 -1
- package/locales/es-ES/providers.json +0 -1
- package/locales/fa-IR/chat.json +7 -0
- package/locales/fa-IR/common.json +2 -0
- package/locales/fa-IR/discover.json +2 -2
- package/locales/fa-IR/models.json +36 -14
- package/locales/fa-IR/onboarding.json +3 -0
- package/locales/fa-IR/plugin.json +22 -1
- package/locales/fa-IR/providers.json +0 -1
- package/locales/fr-FR/chat.json +7 -0
- package/locales/fr-FR/common.json +2 -0
- package/locales/fr-FR/discover.json +2 -2
- package/locales/fr-FR/models.json +95 -13
- package/locales/fr-FR/onboarding.json +3 -0
- package/locales/fr-FR/plugin.json +22 -1
- package/locales/fr-FR/providers.json +0 -1
- package/locales/it-IT/chat.json +7 -0
- package/locales/it-IT/common.json +2 -0
- package/locales/it-IT/discover.json +2 -2
- package/locales/it-IT/models.json +8 -13
- package/locales/it-IT/onboarding.json +3 -0
- package/locales/it-IT/plugin.json +22 -1
- package/locales/it-IT/providers.json +0 -1
- package/locales/ja-JP/chat.json +7 -0
- package/locales/ja-JP/common.json +2 -0
- package/locales/ja-JP/discover.json +2 -2
- package/locales/ja-JP/models.json +76 -8
- package/locales/ja-JP/onboarding.json +3 -0
- package/locales/ja-JP/plugin.json +22 -1
- package/locales/ja-JP/providers.json +0 -1
- package/locales/ko-KR/chat.json +7 -0
- package/locales/ko-KR/common.json +2 -0
- package/locales/ko-KR/discover.json +2 -2
- package/locales/ko-KR/models.json +8 -15
- package/locales/ko-KR/onboarding.json +3 -0
- package/locales/ko-KR/plugin.json +22 -1
- package/locales/ko-KR/providers.json +0 -1
- package/locales/nl-NL/chat.json +7 -0
- package/locales/nl-NL/common.json +2 -0
- package/locales/nl-NL/discover.json +2 -2
- package/locales/nl-NL/models.json +98 -9
- package/locales/nl-NL/onboarding.json +3 -0
- package/locales/nl-NL/plugin.json +22 -1
- package/locales/nl-NL/providers.json +0 -1
- package/locales/pl-PL/chat.json +7 -0
- package/locales/pl-PL/common.json +2 -0
- package/locales/pl-PL/discover.json +2 -2
- package/locales/pl-PL/models.json +38 -13
- package/locales/pl-PL/onboarding.json +3 -0
- package/locales/pl-PL/plugin.json +22 -1
- package/locales/pl-PL/providers.json +0 -1
- package/locales/pt-BR/chat.json +7 -0
- package/locales/pt-BR/common.json +2 -0
- package/locales/pt-BR/discover.json +2 -2
- package/locales/pt-BR/models.json +50 -13
- package/locales/pt-BR/onboarding.json +3 -0
- package/locales/pt-BR/plugin.json +22 -1
- package/locales/pt-BR/providers.json +0 -1
- package/locales/ru-RU/chat.json +7 -0
- package/locales/ru-RU/common.json +2 -0
- package/locales/ru-RU/discover.json +2 -2
- package/locales/ru-RU/models.json +54 -13
- package/locales/ru-RU/onboarding.json +3 -0
- package/locales/ru-RU/plugin.json +22 -1
- package/locales/ru-RU/providers.json +0 -1
- package/locales/tr-TR/chat.json +7 -0
- package/locales/tr-TR/common.json +2 -0
- package/locales/tr-TR/discover.json +2 -2
- package/locales/tr-TR/models.json +40 -13
- package/locales/tr-TR/onboarding.json +3 -0
- package/locales/tr-TR/plugin.json +22 -1
- package/locales/tr-TR/providers.json +0 -1
- package/locales/vi-VN/chat.json +7 -0
- package/locales/vi-VN/common.json +2 -0
- package/locales/vi-VN/discover.json +2 -2
- package/locales/vi-VN/models.json +8 -8
- package/locales/vi-VN/onboarding.json +3 -0
- package/locales/vi-VN/plugin.json +22 -1
- package/locales/vi-VN/providers.json +0 -1
- package/locales/zh-CN/chat.json +7 -0
- package/locales/zh-CN/discover.json +2 -2
- package/locales/zh-CN/models.json +95 -13
- package/locales/zh-CN/onboarding.json +3 -0
- package/locales/zh-CN/plugin.json +22 -1
- package/locales/zh-CN/providers.json +0 -1
- package/locales/zh-TW/chat.json +7 -0
- package/locales/zh-TW/common.json +2 -0
- package/locales/zh-TW/discover.json +2 -2
- package/locales/zh-TW/models.json +86 -13
- package/locales/zh-TW/onboarding.json +3 -0
- package/locales/zh-TW/plugin.json +22 -1
- package/locales/zh-TW/providers.json +0 -1
- package/package.json +1 -1
- package/packages/builtin-tool-agent-builder/package.json +1 -0
- package/packages/builtin-tool-agent-builder/src/client/Inspector/GetAvailableModels/index.tsx +66 -0
- package/packages/builtin-tool-agent-builder/src/client/Inspector/InstallPlugin/index.tsx +63 -0
- package/packages/builtin-tool-agent-builder/src/client/Inspector/SearchMarketTools/index.tsx +64 -0
- package/packages/builtin-tool-agent-builder/src/client/Inspector/UpdateConfig/index.tsx +94 -0
- package/packages/builtin-tool-agent-builder/src/client/Inspector/UpdatePrompt/index.tsx +96 -0
- package/packages/builtin-tool-agent-builder/src/client/Inspector/index.ts +29 -0
- package/packages/builtin-tool-agent-builder/src/client/index.ts +13 -0
- package/packages/builtin-tool-agent-builder/src/executor.ts +132 -0
- package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/ExecuteCode/index.tsx +5 -14
- package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/RunCommand/index.tsx +5 -13
- package/packages/builtin-tool-group-agent-builder/package.json +7 -1
- package/packages/builtin-tool-group-agent-builder/src/ExecutionRuntime/index.ts +331 -87
- package/packages/builtin-tool-group-agent-builder/src/client/Inspector/BatchCreateAgents/index.tsx +110 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Inspector/CreateAgent/index.tsx +72 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Inspector/InviteAgent/index.tsx +57 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Inspector/RemoveAgent/index.tsx +57 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Inspector/SearchAgent/index.tsx +66 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Inspector/UpdateAgentPrompt/index.tsx +120 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Inspector/UpdateGroup/index.tsx +87 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Inspector/UpdateGroupPrompt/index.tsx +99 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Inspector/index.ts +52 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Render/BatchCreateAgents.tsx +103 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Render/UpdateAgentPrompt/index.tsx +36 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Render/UpdateGroupPrompt/index.tsx +36 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Render/index.ts +16 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Streaming/BatchCreateAgents/index.tsx +88 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Streaming/UpdateAgentPrompt/index.tsx +37 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Streaming/UpdateGroupPrompt/index.tsx +35 -0
- package/packages/builtin-tool-group-agent-builder/src/client/Streaming/index.ts +22 -0
- package/packages/builtin-tool-group-agent-builder/src/client/index.ts +26 -0
- package/packages/builtin-tool-group-agent-builder/src/executor.ts +284 -0
- package/packages/builtin-tool-group-agent-builder/src/index.ts +1 -14
- package/packages/builtin-tool-group-agent-builder/src/manifest.ts +160 -15
- package/packages/builtin-tool-group-agent-builder/src/systemRole.ts +232 -46
- package/packages/builtin-tool-group-agent-builder/src/types.ts +191 -41
- package/packages/builtin-tool-group-management/src/client/Inspector/Broadcast/index.tsx +2 -2
- package/packages/builtin-tool-group-management/src/manifest.ts +1 -1
- package/packages/builtin-tool-gtd/src/client/Inspector/ClearTodos/index.tsx +5 -11
- package/packages/builtin-tool-gtd/src/client/Inspector/CompleteTodos/index.tsx +3 -9
- package/packages/builtin-tool-gtd/src/client/Inspector/CreatePlan/index.tsx +6 -15
- package/packages/builtin-tool-gtd/src/client/Inspector/CreateTodos/index.tsx +3 -9
- package/packages/builtin-tool-gtd/src/client/Inspector/ExecTask/index.tsx +6 -17
- package/packages/builtin-tool-gtd/src/client/Inspector/RemoveTodos/index.tsx +3 -9
- package/packages/builtin-tool-gtd/src/client/Inspector/UpdatePlan/index.tsx +3 -9
- package/packages/builtin-tool-gtd/src/client/Inspector/UpdateTodos/index.tsx +3 -9
- package/packages/builtin-tool-knowledge-base/src/client/Inspector/ReadKnowledge/index.tsx +4 -16
- package/packages/builtin-tool-knowledge-base/src/client/Inspector/SearchKnowledgeBase/index.tsx +5 -16
- package/packages/builtin-tool-local-system/src/client/Inspector/EditLocalFile/index.tsx +4 -12
- package/packages/builtin-tool-local-system/src/client/Inspector/GlobLocalFiles/index.tsx +5 -13
- package/packages/builtin-tool-local-system/src/client/Inspector/GrepContent/index.tsx +5 -16
- package/packages/builtin-tool-local-system/src/client/Inspector/ListLocalFiles/index.tsx +5 -16
- package/packages/builtin-tool-local-system/src/client/Inspector/ReadLocalFile/index.tsx +5 -16
- package/packages/builtin-tool-local-system/src/client/Inspector/RenameLocalFile/index.tsx +5 -11
- package/packages/builtin-tool-local-system/src/client/Inspector/RunCommand/index.tsx +5 -13
- package/packages/builtin-tool-local-system/src/client/Inspector/SearchLocalFiles/index.tsx +5 -16
- package/packages/builtin-tool-local-system/src/client/Inspector/WriteLocalFile/index.tsx +6 -15
- package/packages/builtin-tool-notebook/src/client/Inspector/CreateDocument/index.tsx +7 -15
- package/packages/builtin-tool-page-agent/src/client/Inspector/EditTitle/index.tsx +5 -14
- package/packages/builtin-tool-page-agent/src/client/Inspector/GetPageContent/index.tsx +7 -8
- package/packages/builtin-tool-page-agent/src/client/Inspector/InitPage/index.tsx +4 -10
- package/packages/builtin-tool-page-agent/src/client/Inspector/ModifyNodes/index.tsx +3 -9
- package/packages/builtin-tool-page-agent/src/client/Inspector/ReplaceText/index.tsx +5 -11
- package/packages/builtin-tool-web-browsing/src/client/Inspector/CrawlMultiPages/index.tsx +6 -15
- package/packages/builtin-tool-web-browsing/src/client/Inspector/CrawlSinglePage/index.tsx +6 -15
- package/packages/builtin-tool-web-browsing/src/client/Inspector/Search/index.tsx +4 -15
- package/packages/database/src/models/chatGroup.ts +1 -1
- package/packages/model-bank/src/aiModels/aihubmix.ts +2 -1
- package/packages/model-bank/src/aiModels/google.ts +2 -1
- package/packages/model-bank/src/aiModels/infiniai.ts +9 -6
- package/packages/model-bank/src/aiModels/minimax.ts +9 -5
- package/packages/model-bank/src/aiModels/ollamacloud.ts +4 -2
- package/packages/model-bank/src/aiModels/vertexai.ts +2 -1
- package/packages/types/src/agentGroup/index.ts +8 -0
- package/patches/@upstash__qstash.patch +13 -1
- package/src/app/[variants]/(main)/agent/_layout/Sidebar/Header/Nav.tsx +1 -1
- package/src/app/[variants]/(main)/agent/cron/[cronId]/index.tsx +4 -3
- package/src/app/[variants]/(main)/agent/profile/features/ProfileEditor/index.tsx +1 -1
- package/src/app/[variants]/(main)/agent/profile/features/store/action.ts +18 -21
- package/src/app/[variants]/(main)/group/_layout/GroupIdSync.tsx +6 -1
- package/src/app/[variants]/(main)/group/_layout/Sidebar/GroupConfig/AgentProfilePopup.tsx +29 -21
- package/src/app/[variants]/(main)/group/_layout/Sidebar/GroupConfig/GroupMember.tsx +1 -0
- package/src/app/[variants]/(main)/group/_layout/Sidebar/GroupConfig/GroupMemberItem.tsx +35 -18
- package/src/app/[variants]/(main)/group/_layout/Sidebar/Header/AddTopicButon.tsx +2 -10
- package/src/app/[variants]/(main)/group/_layout/Sidebar/Header/Nav.tsx +10 -2
- package/src/app/[variants]/(main)/group/_layout/Sidebar/Header/index.tsx +1 -2
- package/src/app/[variants]/(main)/group/profile/features/AgentBuilder/AgentBuilderProvider.tsx +1 -0
- package/src/app/[variants]/(main)/group/profile/features/AgentBuilder/TopicSelector.tsx +15 -9
- package/src/app/[variants]/(main)/group/profile/features/AgentBuilder/index.tsx +12 -6
- package/src/app/[variants]/(main)/group/profile/features/{ProfileEditor/AgentHeader.tsx → GroupProfile/GroupHeader.tsx} +22 -29
- package/src/app/[variants]/(main)/group/profile/features/GroupProfile/index.tsx +96 -0
- package/src/app/[variants]/(main)/group/profile/features/Header/AgentBuilderToggle.tsx +3 -4
- package/src/app/[variants]/(main)/group/profile/features/Header/AutoSaveHint.tsx +11 -7
- package/src/app/[variants]/(main)/group/profile/features/Header/ChromeTabs/index.tsx +147 -0
- package/src/app/[variants]/(main)/group/profile/features/Header/index.tsx +104 -13
- package/src/app/[variants]/(main)/group/profile/features/MemberProfile/AgentHeader.tsx +222 -0
- package/src/app/[variants]/(main)/group/profile/features/MemberProfile/index.tsx +155 -0
- package/src/app/[variants]/(main)/group/profile/features/ProfileHydration.tsx +63 -5
- package/src/app/[variants]/(main)/group/profile/index.tsx +34 -37
- package/src/app/[variants]/(mobile)/(home)/_layout/SessionHydration.tsx +1 -1
- package/src/app/[variants]/(mobile)/(home)/features/SessionListContent/List/Item/index.tsx +1 -1
- package/src/features/AgentBuilder/index.tsx +16 -1
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Inspector/StatusIndicator.tsx +3 -2
- package/src/features/EditorCanvas/EditorCanvas.test.tsx +206 -0
- package/src/features/EditorCanvas/EditorDataMode.tsx +53 -19
- package/src/features/EditorModal/index.tsx +2 -2
- package/src/features/NavPanel/components/SessionHydration.tsx +1 -1
- package/src/features/ShareModal/ShareImage/ChatList/index.tsx +1 -1
- package/src/features/ShareModal/SharePdf/index.tsx +1 -1
- package/src/hooks/useBidirectionalQuerySync.ts +112 -0
- package/src/locales/default/chat.ts +10 -0
- package/src/locales/default/plugin.ts +22 -1
- package/src/server/modules/AgentRuntime/RuntimeExecutors.ts +45 -45
- package/src/server/modules/KeyVaultsEncrypt/index.ts +6 -6
- package/src/server/modules/S3/index.ts +1 -1
- package/src/server/routers/lambda/agent.ts +24 -0
- package/src/server/routers/lambda/agentGroup.ts +39 -0
- package/src/services/agent.ts +22 -0
- package/src/services/chatGroup/index.ts +14 -0
- package/src/store/agent/selectors/selectors.ts +3 -0
- package/src/store/agentGroup/initialState.ts +6 -0
- package/src/store/agentGroup/selectors/byId.ts +3 -1
- package/src/store/agentGroup/selectors/current.ts +2 -2
- package/src/store/agentGroup/slices/lifecycle.ts +18 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/fixtures/mockStore.ts +1 -1
- package/src/store/chat/slices/aiAgent/actions/__tests__/agentGroup.test.ts +4 -1
- package/src/store/chat/slices/aiAgent/actions/agentGroup.ts +1 -1
- package/src/store/chat/slices/aiChat/actions/__tests__/conversationLifecycle.test.ts +65 -0
- package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +2 -1
- package/src/store/chat/slices/builtinTool/actions/__tests__/search.test.ts +1 -1
- package/src/store/chat/slices/builtinTool/actions/index.ts +1 -6
- package/src/store/chat/slices/message/action.test.ts +5 -5
- package/src/store/chat/slices/message/actions/publicApi.ts +5 -5
- package/src/store/chat/slices/message/initialState.ts +0 -5
- package/src/store/chat/slices/message/selectors/displayMessage.test.ts +4 -4
- package/src/store/chat/slices/plugin/action.test.ts +54 -19
- package/src/store/chat/slices/plugin/actions/pluginTypes.ts +15 -21
- package/src/store/chat/slices/topic/action.test.ts +74 -24
- package/src/store/chat/slices/topic/action.ts +21 -13
- package/src/store/chat/slices/topic/selectors.test.ts +1 -1
- package/src/store/global/initialState.ts +10 -0
- package/src/store/global/selectors/systemStatus.ts +5 -0
- package/src/store/groupProfile/action.ts +168 -0
- package/src/store/groupProfile/index.ts +16 -0
- package/src/{app/[variants]/(main)/group/profile/features/store → store/groupProfile}/initialState.ts +17 -0
- package/src/store/groupProfile/selectors.ts +13 -0
- package/src/store/tool/slices/builtin/executors/index.ts +4 -0
- package/src/styles/text.ts +16 -0
- package/src/tools/inspectors.ts +13 -0
- package/src/tools/renders.ts +3 -0
- package/src/tools/streamings.ts +8 -0
- package/src/app/[variants]/(main)/group/profile/features/EditorCanvas/TypoBar.tsx +0 -129
- package/src/app/[variants]/(main)/group/profile/features/EditorCanvas/index.tsx +0 -138
- package/src/app/[variants]/(main)/group/profile/features/EditorCanvas/useSlashItems.tsx +0 -139
- package/src/app/[variants]/(main)/group/profile/features/ProfileEditor/index.tsx +0 -82
- package/src/app/[variants]/(main)/group/profile/features/ProfileProvider.tsx +0 -20
- package/src/app/[variants]/(main)/group/profile/features/StoreUpdater.tsx +0 -24
- package/src/app/[variants]/(main)/group/profile/features/store/action.ts +0 -163
- package/src/app/[variants]/(main)/group/profile/features/store/index.ts +0 -23
- package/src/app/[variants]/(main)/group/profile/features/store/selectors.ts +0 -7
- package/src/features/EditorModal/EditorCanvas.tsx +0 -84
- package/src/features/EditorModal/Typobar.tsx +0 -139
- package/src/store/chat/slices/builtinTool/actions/agentBuilder.ts +0 -192
- package/src/store/chat/slices/builtinTool/actions/groupAgentBuilder.ts +0 -242
- package/src/tools/executionRuntimes.ts +0 -14
- /package/src/app/[variants]/(main)/group/profile/features/{ProfileEditor → MemberProfile}/AgentTool.tsx +0 -0
- /package/src/app/[variants]/(main)/group/profile/features/{ProfileEditor → MemberProfile}/MentionList/MentionDropdown.tsx +0 -0
- /package/src/app/[variants]/(main)/group/profile/features/{ProfileEditor → MemberProfile}/MentionList/index.tsx +0 -0
- /package/src/app/[variants]/(main)/group/profile/features/{ProfileEditor → MemberProfile}/MentionList/types.ts +0 -0
- /package/src/app/[variants]/(main)/group/profile/features/{ProfileEditor → MemberProfile}/MentionList/useMentionItems.tsx +0 -0
|
@@ -346,22 +346,6 @@ describe('topic action', () => {
|
|
|
346
346
|
expect(refreshMessagesSpy).toHaveBeenCalled();
|
|
347
347
|
});
|
|
348
348
|
|
|
349
|
-
it('should support boolean as second parameter for backward compatibility', async () => {
|
|
350
|
-
const topicId = 'topic-id';
|
|
351
|
-
const { result } = renderHook(() => useChatStore());
|
|
352
|
-
|
|
353
|
-
const refreshMessagesSpy = vi.spyOn(result.current, 'refreshMessages');
|
|
354
|
-
|
|
355
|
-
// Call with boolean (old API)
|
|
356
|
-
await act(async () => {
|
|
357
|
-
await result.current.switchTopic(topicId, true);
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
expect(useChatStore.getState().activeTopicId).toBe(topicId);
|
|
361
|
-
// Should not call refreshMessages when skipRefreshMessage is true
|
|
362
|
-
expect(refreshMessagesSpy).not.toHaveBeenCalled();
|
|
363
|
-
});
|
|
364
|
-
|
|
365
349
|
it('should support options object as second parameter', async () => {
|
|
366
350
|
const topicId = 'topic-id';
|
|
367
351
|
const { result } = renderHook(() => useChatStore());
|
|
@@ -377,7 +361,7 @@ describe('topic action', () => {
|
|
|
377
361
|
expect(refreshMessagesSpy).not.toHaveBeenCalled();
|
|
378
362
|
});
|
|
379
363
|
|
|
380
|
-
it('should clear new key data when switching to
|
|
364
|
+
it('should clear new key data when switching to null (main scope)', async () => {
|
|
381
365
|
const { result } = renderHook(() => useChatStore());
|
|
382
366
|
const activeAgentId = 'test-agent-id';
|
|
383
367
|
const newKey = messageMapKey({ agentId: activeAgentId, topicId: null });
|
|
@@ -398,9 +382,9 @@ describe('topic action', () => {
|
|
|
398
382
|
|
|
399
383
|
const replaceMessagesSpy = vi.spyOn(result.current, 'replaceMessages');
|
|
400
384
|
|
|
401
|
-
// Switch to new state (id =
|
|
385
|
+
// Switch to new state (id = null)
|
|
402
386
|
await act(async () => {
|
|
403
|
-
await result.current.switchTopic(
|
|
387
|
+
await result.current.switchTopic(null, { skipRefreshMessage: true });
|
|
404
388
|
});
|
|
405
389
|
|
|
406
390
|
// Verify replaceMessages was called to clear the new key
|
|
@@ -418,7 +402,7 @@ describe('topic action', () => {
|
|
|
418
402
|
expect(useChatStore.getState().activeTopicId).toBeNull();
|
|
419
403
|
});
|
|
420
404
|
|
|
421
|
-
it('should clear new key data when switching to
|
|
405
|
+
it('should clear new key data when switching to null (group scope)', async () => {
|
|
422
406
|
const { result } = renderHook(() => useChatStore());
|
|
423
407
|
const activeAgentId = 'test-agent-id';
|
|
424
408
|
const activeGroupId = 'test-group-id';
|
|
@@ -434,9 +418,9 @@ describe('topic action', () => {
|
|
|
434
418
|
|
|
435
419
|
const replaceMessagesSpy = vi.spyOn(result.current, 'replaceMessages');
|
|
436
420
|
|
|
437
|
-
// Switch to new state
|
|
421
|
+
// Switch to new state with null
|
|
438
422
|
await act(async () => {
|
|
439
|
-
await result.current.switchTopic(
|
|
423
|
+
await result.current.switchTopic(null, { skipRefreshMessage: true });
|
|
440
424
|
});
|
|
441
425
|
|
|
442
426
|
// Verify replaceMessages was called with group scope
|
|
@@ -464,9 +448,9 @@ describe('topic action', () => {
|
|
|
464
448
|
|
|
465
449
|
const replaceMessagesSpy = vi.spyOn(result.current, 'replaceMessages');
|
|
466
450
|
|
|
467
|
-
// Switch to
|
|
451
|
+
// Switch to null with explicit scope
|
|
468
452
|
await act(async () => {
|
|
469
|
-
await result.current.switchTopic(
|
|
453
|
+
await result.current.switchTopic(null, { skipRefreshMessage: true, scope: 'group' });
|
|
470
454
|
});
|
|
471
455
|
|
|
472
456
|
// Verify replaceMessages was called with explicit scope
|
|
@@ -478,6 +462,28 @@ describe('topic action', () => {
|
|
|
478
462
|
});
|
|
479
463
|
});
|
|
480
464
|
|
|
465
|
+
it('should NOT clear new key data when switching with undefined (backward compatibility)', async () => {
|
|
466
|
+
const { result } = renderHook(() => useChatStore());
|
|
467
|
+
const activeAgentId = 'test-agent-id';
|
|
468
|
+
|
|
469
|
+
await act(async () => {
|
|
470
|
+
useChatStore.setState({
|
|
471
|
+
activeAgentId,
|
|
472
|
+
activeTopicId: 'existing-topic',
|
|
473
|
+
});
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
const replaceMessagesSpy = vi.spyOn(result.current, 'replaceMessages');
|
|
477
|
+
|
|
478
|
+
// Switch with undefined (should NOT clear because id !== null)
|
|
479
|
+
await act(async () => {
|
|
480
|
+
await result.current.switchTopic(undefined, { skipRefreshMessage: true });
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
// replaceMessages should NOT be called when switching with undefined
|
|
484
|
+
expect(replaceMessagesSpy).not.toHaveBeenCalled();
|
|
485
|
+
});
|
|
486
|
+
|
|
481
487
|
it('should not clear new key data when switching to an existing topic', async () => {
|
|
482
488
|
const { result } = renderHook(() => useChatStore());
|
|
483
489
|
const activeAgentId = 'test-agent-id';
|
|
@@ -499,6 +505,50 @@ describe('topic action', () => {
|
|
|
499
505
|
// replaceMessages should not be called when switching to existing topic
|
|
500
506
|
expect(replaceMessagesSpy).not.toHaveBeenCalled();
|
|
501
507
|
});
|
|
508
|
+
|
|
509
|
+
it('should clear new key data when clearNewKey option is true (even with existing topic)', async () => {
|
|
510
|
+
const { result } = renderHook(() => useChatStore());
|
|
511
|
+
const activeAgentId = 'test-agent-id';
|
|
512
|
+
const newKey = messageMapKey({ agentId: activeAgentId, topicId: null });
|
|
513
|
+
|
|
514
|
+
// Setup initial state with some messages in the new key
|
|
515
|
+
await act(async () => {
|
|
516
|
+
useChatStore.setState({
|
|
517
|
+
activeAgentId,
|
|
518
|
+
activeTopicId: undefined,
|
|
519
|
+
dbMessagesMap: {
|
|
520
|
+
[newKey]: [{ id: 'msg-1' }, { id: 'msg-2' }] as any,
|
|
521
|
+
},
|
|
522
|
+
messagesMap: {
|
|
523
|
+
[newKey]: [{ id: 'msg-1' }, { id: 'msg-2' }] as any,
|
|
524
|
+
},
|
|
525
|
+
});
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
const replaceMessagesSpy = vi.spyOn(result.current, 'replaceMessages');
|
|
529
|
+
|
|
530
|
+
// Switch to an existing topic with clearNewKey option
|
|
531
|
+
await act(async () => {
|
|
532
|
+
await result.current.switchTopic('new-created-topic-id', {
|
|
533
|
+
clearNewKey: true,
|
|
534
|
+
skipRefreshMessage: true,
|
|
535
|
+
});
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
// replaceMessages should be called to clear the new key
|
|
539
|
+
expect(replaceMessagesSpy).toHaveBeenCalledWith([], {
|
|
540
|
+
context: {
|
|
541
|
+
agentId: activeAgentId,
|
|
542
|
+
groupId: undefined,
|
|
543
|
+
scope: 'main',
|
|
544
|
+
topicId: null,
|
|
545
|
+
},
|
|
546
|
+
action: expect.any(String),
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
// Verify activeTopicId is set to the new topic
|
|
550
|
+
expect(useChatStore.getState().activeTopicId).toBe('new-created-topic-id');
|
|
551
|
+
});
|
|
502
552
|
});
|
|
503
553
|
describe('removeSessionTopics', () => {
|
|
504
554
|
it('should remove all topics from the current session and refresh the topic list', async () => {
|
|
@@ -48,6 +48,12 @@ type CronTopicsGroupWithJobInfo = {
|
|
|
48
48
|
* Options for switchTopic action
|
|
49
49
|
*/
|
|
50
50
|
export interface SwitchTopicOptions {
|
|
51
|
+
/**
|
|
52
|
+
* Clear the _new key data even when switching to an existing topic
|
|
53
|
+
* This is useful when creating a new topic, where the _new key data should be cleared
|
|
54
|
+
* @default false
|
|
55
|
+
*/
|
|
56
|
+
clearNewKey?: boolean;
|
|
51
57
|
/**
|
|
52
58
|
* Explicit scope for clearing new key data
|
|
53
59
|
* If not provided, will be inferred from store state (activeGroupId)
|
|
@@ -81,10 +87,10 @@ export interface ChatTopicAction {
|
|
|
81
87
|
summaryTopicTitle: (topicId: string, messages: UIChatMessage[]) => Promise<void>;
|
|
82
88
|
/**
|
|
83
89
|
* Switch to a topic or create new topic state
|
|
84
|
-
* @param id - Topic ID to switch to, or
|
|
85
|
-
* @param options - Options object
|
|
90
|
+
* @param id - Topic ID to switch to, or null to switch to "new" state (clears _new key data)
|
|
91
|
+
* @param options - Options object for configuring the switch behavior
|
|
86
92
|
*/
|
|
87
|
-
switchTopic: (id?: string, options?:
|
|
93
|
+
switchTopic: (id?: string | null, options?: SwitchTopicOptions) => Promise<void>;
|
|
88
94
|
/**
|
|
89
95
|
* Update topic metadata
|
|
90
96
|
* @param id - Topic ID to update
|
|
@@ -151,7 +157,7 @@ export const chatTopic: StateCreator<
|
|
|
151
157
|
const { switchTopic, saveToTopic, refreshMessages, activeTopicId } = get();
|
|
152
158
|
const hasTopic = !!activeTopicId;
|
|
153
159
|
|
|
154
|
-
if (hasTopic) switchTopic();
|
|
160
|
+
if (hasTopic) switchTopic(null);
|
|
155
161
|
else {
|
|
156
162
|
await saveToTopic();
|
|
157
163
|
refreshMessages();
|
|
@@ -521,15 +527,17 @@ export const chatTopic: StateCreator<
|
|
|
521
527
|
),
|
|
522
528
|
|
|
523
529
|
switchTopic: async (id, options) => {
|
|
524
|
-
|
|
525
|
-
const opts: SwitchTopicOptions =
|
|
526
|
-
typeof options === 'boolean' ? { skipRefreshMessage: options } : (options ?? {});
|
|
530
|
+
const opts = options ?? {};
|
|
527
531
|
|
|
528
532
|
const { activeAgentId, activeGroupId } = get();
|
|
529
533
|
|
|
530
|
-
//
|
|
534
|
+
// Clear the _new key data in the following cases:
|
|
535
|
+
// 1. When id is explicitly null (switching to empty topic state)
|
|
536
|
+
// 2. When clearNewKey option is explicitly true
|
|
531
537
|
// This prevents stale data from previous conversations showing up
|
|
532
|
-
|
|
538
|
+
const shouldClearNewKey = id === null || opts.clearNewKey;
|
|
539
|
+
|
|
540
|
+
if (shouldClearNewKey && activeAgentId) {
|
|
533
541
|
// Determine scope: use explicit scope from options, or infer from activeGroupId
|
|
534
542
|
const scope = opts.scope ?? (activeGroupId ? 'group' : 'main');
|
|
535
543
|
|
|
@@ -562,7 +570,7 @@ export const chatTopic: StateCreator<
|
|
|
562
570
|
await refreshTopic();
|
|
563
571
|
|
|
564
572
|
// switch to default topic
|
|
565
|
-
switchTopic();
|
|
573
|
+
switchTopic(null);
|
|
566
574
|
},
|
|
567
575
|
|
|
568
576
|
removeGroupTopics: async (groupId: string) => {
|
|
@@ -580,7 +588,7 @@ export const chatTopic: StateCreator<
|
|
|
580
588
|
await refreshTopic();
|
|
581
589
|
|
|
582
590
|
// switch to default topic
|
|
583
|
-
switchTopic();
|
|
591
|
+
switchTopic(null);
|
|
584
592
|
},
|
|
585
593
|
removeAllTopics: async () => {
|
|
586
594
|
const { refreshTopic } = get();
|
|
@@ -598,7 +606,7 @@ export const chatTopic: StateCreator<
|
|
|
598
606
|
await refreshTopic();
|
|
599
607
|
|
|
600
608
|
// switch back to default topic
|
|
601
|
-
if (activeTopicId === id) switchTopic();
|
|
609
|
+
if (activeTopicId === id) switchTopic(null);
|
|
602
610
|
},
|
|
603
611
|
removeUnstarredTopic: async () => {
|
|
604
612
|
const { refreshTopic, switchTopic } = get();
|
|
@@ -608,7 +616,7 @@ export const chatTopic: StateCreator<
|
|
|
608
616
|
await refreshTopic();
|
|
609
617
|
|
|
610
618
|
// 切换到默认 topic
|
|
611
|
-
switchTopic();
|
|
619
|
+
switchTopic(null);
|
|
612
620
|
},
|
|
613
621
|
|
|
614
622
|
// Internal process method of the topics
|
|
@@ -35,7 +35,7 @@ const topicDataMap = createTopicDataMap('test');
|
|
|
35
35
|
|
|
36
36
|
describe('topicSelectors', () => {
|
|
37
37
|
describe('currentTopics', () => {
|
|
38
|
-
it('should return undefined if there are no topics with
|
|
38
|
+
it('should return undefined if there are no topics with activeAgentId', () => {
|
|
39
39
|
const topics = topicSelectors.currentTopics(initialStore);
|
|
40
40
|
expect(topics).toBeUndefined();
|
|
41
41
|
});
|
|
@@ -75,6 +75,10 @@ export enum ProfileTabs {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
export interface SystemStatus {
|
|
78
|
+
/**
|
|
79
|
+
* Agent Builder panel width
|
|
80
|
+
*/
|
|
81
|
+
agentBuilderPanelWidth?: number;
|
|
78
82
|
/**
|
|
79
83
|
* number of agents (defaultList) to display
|
|
80
84
|
*/
|
|
@@ -89,6 +93,10 @@ export interface SystemStatus {
|
|
|
89
93
|
expandTopicGroupKeys?: string[];
|
|
90
94
|
fileManagerViewMode?: 'list' | 'masonry';
|
|
91
95
|
filePanelWidth: number;
|
|
96
|
+
/**
|
|
97
|
+
* Group Agent Builder panel width
|
|
98
|
+
*/
|
|
99
|
+
groupAgentBuilderPanelWidth?: number;
|
|
92
100
|
hideGemini2_5FlashImagePreviewChineseWarning?: boolean;
|
|
93
101
|
hidePWAInstaller?: boolean;
|
|
94
102
|
hideThreadLimitAlert?: boolean;
|
|
@@ -180,6 +188,7 @@ export interface GlobalState {
|
|
|
180
188
|
}
|
|
181
189
|
|
|
182
190
|
export const INITIAL_STATUS = {
|
|
191
|
+
agentBuilderPanelWidth: 360,
|
|
183
192
|
agentPageSize: 10,
|
|
184
193
|
chatInputHeight: 64,
|
|
185
194
|
disabledModelProvidersSortType: 'default',
|
|
@@ -188,6 +197,7 @@ export const INITIAL_STATUS = {
|
|
|
188
197
|
expandSessionGroupKeys: [SessionDefaultGroup.Pinned, SessionDefaultGroup.Default],
|
|
189
198
|
fileManagerViewMode: 'list' as const,
|
|
190
199
|
filePanelWidth: 320,
|
|
200
|
+
groupAgentBuilderPanelWidth: 360,
|
|
191
201
|
hideGemini2_5FlashImagePreviewChineseWarning: false,
|
|
192
202
|
hidePWAInstaller: false,
|
|
193
203
|
hideThreadLimitAlert: false,
|
|
@@ -2,6 +2,8 @@ import { type GlobalState, INITIAL_STATUS } from '../initialState';
|
|
|
2
2
|
|
|
3
3
|
export const systemStatus = (s: GlobalState) => s.status;
|
|
4
4
|
|
|
5
|
+
const agentBuilderPanelWidth = (s: GlobalState) => s.status.agentBuilderPanelWidth || 360;
|
|
6
|
+
|
|
5
7
|
const sessionGroupKeys = (s: GlobalState): string[] =>
|
|
6
8
|
s.status.expandSessionGroupKeys || INITIAL_STATUS.expandSessionGroupKeys;
|
|
7
9
|
|
|
@@ -37,6 +39,7 @@ const leftPanelWidth = (s: GlobalState): number => {
|
|
|
37
39
|
};
|
|
38
40
|
const portalWidth = (s: GlobalState) => s.status.portalWidth || 400;
|
|
39
41
|
const filePanelWidth = (s: GlobalState) => s.status.filePanelWidth;
|
|
42
|
+
const groupAgentBuilderPanelWidth = (s: GlobalState) => s.status.groupAgentBuilderPanelWidth || 360;
|
|
40
43
|
const imagePanelWidth = (s: GlobalState) => s.status.imagePanelWidth;
|
|
41
44
|
const imageTopicPanelWidth = (s: GlobalState) => s.status.imageTopicPanelWidth;
|
|
42
45
|
const wideScreen = (s: GlobalState) => !s.status.noWideScreen;
|
|
@@ -58,6 +61,7 @@ const tokenDisplayFormatShort = (s: GlobalState) =>
|
|
|
58
61
|
s.status.tokenDisplayFormatShort !== undefined ? s.status.tokenDisplayFormatShort : true;
|
|
59
62
|
|
|
60
63
|
export const systemStatusSelectors = {
|
|
64
|
+
agentBuilderPanelWidth,
|
|
61
65
|
agentPageSize,
|
|
62
66
|
chatInputHeight,
|
|
63
67
|
disabledModelProvidersSortType,
|
|
@@ -65,6 +69,7 @@ export const systemStatusSelectors = {
|
|
|
65
69
|
expandInputActionbar,
|
|
66
70
|
filePanelWidth,
|
|
67
71
|
getAgentSystemRoleExpanded,
|
|
72
|
+
groupAgentBuilderPanelWidth,
|
|
68
73
|
hidePWAInstaller,
|
|
69
74
|
imagePanelWidth,
|
|
70
75
|
imageTopicPanelWidth,
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { debounce } from 'es-toolkit/compat';
|
|
2
|
+
import { type StateCreator } from 'zustand';
|
|
3
|
+
|
|
4
|
+
import { EDITOR_DEBOUNCE_TIME, EDITOR_MAX_WAIT } from '@/const/index';
|
|
5
|
+
|
|
6
|
+
import { type SaveState, type SaveStatus, type State, initialState } from './initialState';
|
|
7
|
+
|
|
8
|
+
type SaveContentPayload = {
|
|
9
|
+
content: string;
|
|
10
|
+
editorData: Record<string, any>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export interface Action {
|
|
14
|
+
appendStreamingContent: (chunk: string) => void;
|
|
15
|
+
finishStreaming: (saveCallback: (payload: SaveContentPayload) => Promise<void>) => Promise<void>;
|
|
16
|
+
flushSave: () => void;
|
|
17
|
+
handleContentChange: (saveCallback: (payload: SaveContentPayload) => Promise<void>) => void;
|
|
18
|
+
setActiveTabId: (tabId: string) => void;
|
|
19
|
+
setChatPanelExpanded: (expanded: boolean | ((prev: boolean) => boolean)) => void;
|
|
20
|
+
updateSaveStatus: (tabId: string, status: SaveStatus) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type Store = State & Action;
|
|
24
|
+
|
|
25
|
+
// Store the latest saveCallback and tabId references to avoid stale closures
|
|
26
|
+
let saveCallbackRef: ((payload: SaveContentPayload) => Promise<void>) | null = null;
|
|
27
|
+
let currentTabIdRef: string | null = null;
|
|
28
|
+
|
|
29
|
+
const DEFAULT_SAVE_STATE: SaveState = { lastUpdatedTime: null, saveStatus: 'idle' };
|
|
30
|
+
|
|
31
|
+
export const store: StateCreator<Store> = (set, get) => {
|
|
32
|
+
const updateSaveStatusInternal = (tabId: string, status: SaveStatus) => {
|
|
33
|
+
const { saveStateMap } = get();
|
|
34
|
+
const currentState = saveStateMap[tabId] || DEFAULT_SAVE_STATE;
|
|
35
|
+
set({
|
|
36
|
+
saveStateMap: {
|
|
37
|
+
...saveStateMap,
|
|
38
|
+
[tabId]: {
|
|
39
|
+
...currentState,
|
|
40
|
+
lastUpdatedTime: status === 'saved' ? new Date() : currentState.lastUpdatedTime,
|
|
41
|
+
saveStatus: status,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Create debounced save that uses the latest callback reference
|
|
48
|
+
const debouncedSave = debounce(
|
|
49
|
+
async (payload: SaveContentPayload) => {
|
|
50
|
+
const tabId = currentTabIdRef;
|
|
51
|
+
if (!tabId) return;
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
if (saveCallbackRef) {
|
|
55
|
+
await saveCallbackRef(payload);
|
|
56
|
+
updateSaveStatusInternal(tabId, 'saved');
|
|
57
|
+
}
|
|
58
|
+
} catch (error) {
|
|
59
|
+
console.error('[ProfileEditor] Failed to save:', error);
|
|
60
|
+
updateSaveStatusInternal(tabId, 'idle');
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
EDITOR_DEBOUNCE_TIME,
|
|
64
|
+
{ leading: false, maxWait: EDITOR_MAX_WAIT, trailing: true },
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
...initialState,
|
|
69
|
+
|
|
70
|
+
appendStreamingContent: (chunk) => {
|
|
71
|
+
const currentContent = get().streamingContent || '';
|
|
72
|
+
const newContent = currentContent + chunk;
|
|
73
|
+
set({ streamingContent: newContent });
|
|
74
|
+
|
|
75
|
+
const { editor } = get();
|
|
76
|
+
if (editor) {
|
|
77
|
+
try {
|
|
78
|
+
editor.setDocument('markdown', newContent);
|
|
79
|
+
} catch {
|
|
80
|
+
// Ignore errors during streaming updates
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
finishStreaming: async (saveCallback) => {
|
|
86
|
+
const { activeTabId, editor, streamingContent } = get();
|
|
87
|
+
if (!streamingContent) {
|
|
88
|
+
set({ streamingInProgress: false });
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
let finalContent = streamingContent;
|
|
93
|
+
let editorData = {};
|
|
94
|
+
|
|
95
|
+
if (editor) {
|
|
96
|
+
try {
|
|
97
|
+
finalContent = (editor.getDocument('markdown') as unknown as string) || streamingContent;
|
|
98
|
+
editorData = editor.getDocument('json') as unknown as Record<string, any>;
|
|
99
|
+
} catch {
|
|
100
|
+
// Use streaming content if editor read fails
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
updateSaveStatusInternal(activeTabId, 'saving');
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
await saveCallback({
|
|
108
|
+
content: finalContent,
|
|
109
|
+
editorData: structuredClone(editorData || {}),
|
|
110
|
+
});
|
|
111
|
+
updateSaveStatusInternal(activeTabId, 'saved');
|
|
112
|
+
} catch (error) {
|
|
113
|
+
console.error('[ProfileEditor] Failed to save streaming content:', error);
|
|
114
|
+
updateSaveStatusInternal(activeTabId, 'idle');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
set({
|
|
118
|
+
streamingContent: undefined,
|
|
119
|
+
streamingInProgress: false,
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
flushSave: () => {
|
|
124
|
+
debouncedSave.flush();
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
handleContentChange: (saveCallback) => {
|
|
128
|
+
const { activeTabId, editor } = get();
|
|
129
|
+
if (!editor) return;
|
|
130
|
+
|
|
131
|
+
// Always update refs to use the latest callback and tabId
|
|
132
|
+
saveCallbackRef = saveCallback;
|
|
133
|
+
currentTabIdRef = activeTabId;
|
|
134
|
+
|
|
135
|
+
// Set saving status immediately when user makes changes
|
|
136
|
+
updateSaveStatusInternal(activeTabId, 'saving');
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
const markdownContent = (editor.getDocument('markdown') as unknown as string) || '';
|
|
140
|
+
const jsonContent = editor.getDocument('json') as unknown as Record<string, any>;
|
|
141
|
+
|
|
142
|
+
debouncedSave({
|
|
143
|
+
content: markdownContent || '',
|
|
144
|
+
editorData: structuredClone(jsonContent || {}),
|
|
145
|
+
});
|
|
146
|
+
} catch (error) {
|
|
147
|
+
console.error('[ProfileEditor] Failed to read editor content:', error);
|
|
148
|
+
updateSaveStatusInternal(activeTabId, 'idle');
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
setActiveTabId: (tabId) => {
|
|
153
|
+
set({ activeTabId: tabId });
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
setChatPanelExpanded: (expanded) => {
|
|
157
|
+
if (typeof expanded === 'function') {
|
|
158
|
+
set((state) => ({ chatPanelExpanded: expanded(state.chatPanelExpanded) }));
|
|
159
|
+
} else {
|
|
160
|
+
set({ chatPanelExpanded: expanded });
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
updateSaveStatus: (tabId, status) => {
|
|
165
|
+
updateSaveStatusInternal(tabId, status);
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { shallow } from 'zustand/shallow';
|
|
4
|
+
import { createWithEqualityFn } from 'zustand/traditional';
|
|
5
|
+
|
|
6
|
+
import { createDevtools } from '@/store/middleware/createDevtools';
|
|
7
|
+
|
|
8
|
+
import { type Store, store } from './action';
|
|
9
|
+
|
|
10
|
+
export type { PublicState, State } from './initialState';
|
|
11
|
+
|
|
12
|
+
const devtools = createDevtools('group_profile');
|
|
13
|
+
|
|
14
|
+
export const useGroupProfileStore = createWithEqualityFn<Store>()(devtools(store), shallow);
|
|
15
|
+
|
|
16
|
+
export { selectors } from './selectors';
|
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
import { type IEditor } from '@lobehub/editor';
|
|
2
2
|
|
|
3
|
+
export type SaveStatus = 'idle' | 'saving' | 'saved';
|
|
4
|
+
|
|
5
|
+
export interface SaveState {
|
|
6
|
+
lastUpdatedTime?: Date | null;
|
|
7
|
+
saveStatus: SaveStatus;
|
|
8
|
+
}
|
|
9
|
+
|
|
3
10
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
4
11
|
export interface PublicState {}
|
|
5
12
|
|
|
6
13
|
export interface State extends PublicState {
|
|
14
|
+
/**
|
|
15
|
+
* Active tab ID - 'group' for group settings, or agent ID for member editor
|
|
16
|
+
*/
|
|
17
|
+
activeTabId: string;
|
|
7
18
|
chatPanelExpanded: boolean;
|
|
8
19
|
editor?: IEditor;
|
|
9
20
|
editorState?: any; // EditorState from useEditorState hook
|
|
21
|
+
/**
|
|
22
|
+
* Save state map by tab ID (key: 'group' | agentId)
|
|
23
|
+
*/
|
|
24
|
+
saveStateMap: Record<string, SaveState>;
|
|
10
25
|
/**
|
|
11
26
|
* Content being streamed from AI
|
|
12
27
|
*/
|
|
@@ -18,7 +33,9 @@ export interface State extends PublicState {
|
|
|
18
33
|
}
|
|
19
34
|
|
|
20
35
|
export const initialState: State = {
|
|
36
|
+
activeTabId: 'group',
|
|
21
37
|
chatPanelExpanded: true,
|
|
38
|
+
saveStateMap: {},
|
|
22
39
|
streamingContent: undefined,
|
|
23
40
|
streamingInProgress: false,
|
|
24
41
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Store } from './action';
|
|
2
|
+
import { type SaveState } from './initialState';
|
|
3
|
+
|
|
4
|
+
const DEFAULT_SAVE_STATE: SaveState = { lastUpdatedTime: null, saveStatus: 'idle' };
|
|
5
|
+
|
|
6
|
+
const getSaveState = (tabId: string) => (s: Store) => s.saveStateMap[tabId] || DEFAULT_SAVE_STATE;
|
|
7
|
+
|
|
8
|
+
export const selectors = {
|
|
9
|
+
chatPanelExpanded: (s: Store) => s.chatPanelExpanded,
|
|
10
|
+
editor: (s: Store) => s.editor,
|
|
11
|
+
editorState: (s: Store) => s.editorState,
|
|
12
|
+
getSaveState,
|
|
13
|
+
};
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* Central registry for all builtin tool executors.
|
|
5
5
|
* Executors are registered as class instances by identifier.
|
|
6
6
|
*/
|
|
7
|
+
import { agentBuilderExecutor } from '@lobechat/builtin-tool-agent-builder/executor';
|
|
8
|
+
import { groupAgentBuilderExecutor } from '@lobechat/builtin-tool-group-agent-builder/executor';
|
|
7
9
|
import { groupManagementExecutor } from '@lobechat/builtin-tool-group-management/executor';
|
|
8
10
|
import { gtdExecutor } from '@lobechat/builtin-tool-gtd/executor';
|
|
9
11
|
import { knowledgeBaseExecutor } from '@lobechat/builtin-tool-knowledge-base/executor';
|
|
@@ -117,6 +119,8 @@ const registerExecutors = (executors: IBuiltinToolExecutor[]): void => {
|
|
|
117
119
|
|
|
118
120
|
// Register all executor instances
|
|
119
121
|
registerExecutors([
|
|
122
|
+
agentBuilderExecutor,
|
|
123
|
+
groupAgentBuilderExecutor,
|
|
120
124
|
groupManagementExecutor,
|
|
121
125
|
gtdExecutor,
|
|
122
126
|
knowledgeBaseExecutor,
|
package/src/styles/text.ts
CHANGED
|
@@ -12,6 +12,22 @@ export const lineEllipsis = (line: number) =>
|
|
|
12
12
|
|
|
13
13
|
export const oneLineEllipsis = lineEllipsis(1);
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Inspector text style for builtin tool inspectors
|
|
17
|
+
* Combines oneLineEllipsis with secondary text color
|
|
18
|
+
*/
|
|
19
|
+
export const inspectorTextStyles = createStaticStyles(({ css, cssVar }) => ({
|
|
20
|
+
root: css`
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
display: -webkit-box;
|
|
23
|
+
-webkit-box-orient: vertical;
|
|
24
|
+
-webkit-line-clamp: 1;
|
|
25
|
+
|
|
26
|
+
color: ${cssVar.colorTextSecondary};
|
|
27
|
+
text-overflow: ellipsis;
|
|
28
|
+
`,
|
|
29
|
+
}));
|
|
30
|
+
|
|
15
31
|
/**
|
|
16
32
|
* Highlight underline effect using gradient background
|
|
17
33
|
* - primary: default blue highlight
|
package/src/tools/inspectors.ts
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AgentBuilderInspectors,
|
|
3
|
+
AgentBuilderManifest,
|
|
4
|
+
} from '@lobechat/builtin-tool-agent-builder/client';
|
|
1
5
|
import {
|
|
2
6
|
CloudSandboxIdentifier,
|
|
3
7
|
CloudSandboxInspectors,
|
|
4
8
|
} from '@lobechat/builtin-tool-cloud-sandbox/client';
|
|
9
|
+
import {
|
|
10
|
+
GroupAgentBuilderInspectors,
|
|
11
|
+
GroupAgentBuilderManifest,
|
|
12
|
+
} from '@lobechat/builtin-tool-group-agent-builder/client';
|
|
5
13
|
import {
|
|
6
14
|
GroupManagementInspectors,
|
|
7
15
|
GroupManagementManifest,
|
|
@@ -31,7 +39,12 @@ import { type BuiltinInspector } from '@lobechat/types';
|
|
|
31
39
|
* of tool calls in the conversation UI.
|
|
32
40
|
*/
|
|
33
41
|
const BuiltinToolInspectors: Record<string, Record<string, BuiltinInspector>> = {
|
|
42
|
+
[AgentBuilderManifest.identifier]: AgentBuilderInspectors as Record<string, BuiltinInspector>,
|
|
34
43
|
[CloudSandboxIdentifier]: CloudSandboxInspectors as Record<string, BuiltinInspector>,
|
|
44
|
+
[GroupAgentBuilderManifest.identifier]: GroupAgentBuilderInspectors as Record<
|
|
45
|
+
string,
|
|
46
|
+
BuiltinInspector
|
|
47
|
+
>,
|
|
35
48
|
[GroupManagementManifest.identifier]: GroupManagementInspectors as Record<
|
|
36
49
|
string,
|
|
37
50
|
BuiltinInspector
|
package/src/tools/renders.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { AgentBuilderManifest } from '@lobechat/builtin-tool-agent-builder';
|
|
|
2
2
|
import { AgentBuilderRenders } from '@lobechat/builtin-tool-agent-builder/client';
|
|
3
3
|
import { CloudSandboxManifest } from '@lobechat/builtin-tool-cloud-sandbox';
|
|
4
4
|
import { CloudSandboxRenders } from '@lobechat/builtin-tool-cloud-sandbox/client';
|
|
5
|
+
import { GroupAgentBuilderManifest } from '@lobechat/builtin-tool-group-agent-builder';
|
|
6
|
+
import { GroupAgentBuilderRenders } from '@lobechat/builtin-tool-group-agent-builder/client';
|
|
5
7
|
import { GroupManagementManifest } from '@lobechat/builtin-tool-group-management';
|
|
6
8
|
import { GroupManagementRenders } from '@lobechat/builtin-tool-group-management/client';
|
|
7
9
|
import { GTDManifest, GTDRenders } from '@lobechat/builtin-tool-gtd/client';
|
|
@@ -27,6 +29,7 @@ import { type BuiltinRender } from '@lobechat/types';
|
|
|
27
29
|
const BuiltinToolsRenders: Record<string, Record<string, BuiltinRender>> = {
|
|
28
30
|
[AgentBuilderManifest.identifier]: AgentBuilderRenders as Record<string, BuiltinRender>,
|
|
29
31
|
[CloudSandboxManifest.identifier]: CloudSandboxRenders as Record<string, BuiltinRender>,
|
|
32
|
+
[GroupAgentBuilderManifest.identifier]: GroupAgentBuilderRenders as Record<string, BuiltinRender>,
|
|
30
33
|
[GroupManagementManifest.identifier]: GroupManagementRenders as Record<string, BuiltinRender>,
|
|
31
34
|
[GTDManifest.identifier]: GTDRenders as Record<string, BuiltinRender>,
|
|
32
35
|
[NotebookManifest.identifier]: NotebookRenders as Record<string, BuiltinRender>,
|
package/src/tools/streamings.ts
CHANGED
|
@@ -2,6 +2,10 @@ import {
|
|
|
2
2
|
CloudSandboxManifest,
|
|
3
3
|
CloudSandboxStreamings,
|
|
4
4
|
} from '@lobechat/builtin-tool-cloud-sandbox/client';
|
|
5
|
+
import {
|
|
6
|
+
GroupAgentBuilderManifest,
|
|
7
|
+
GroupAgentBuilderStreamings,
|
|
8
|
+
} from '@lobechat/builtin-tool-group-agent-builder/client';
|
|
5
9
|
import {
|
|
6
10
|
GroupManagementManifest,
|
|
7
11
|
GroupManagementStreamings,
|
|
@@ -24,6 +28,10 @@ import { type BuiltinStreaming } from '@lobechat/types';
|
|
|
24
28
|
*/
|
|
25
29
|
const BuiltinToolStreamings: Record<string, Record<string, BuiltinStreaming>> = {
|
|
26
30
|
[CloudSandboxManifest.identifier]: CloudSandboxStreamings as Record<string, BuiltinStreaming>,
|
|
31
|
+
[GroupAgentBuilderManifest.identifier]: GroupAgentBuilderStreamings as Record<
|
|
32
|
+
string,
|
|
33
|
+
BuiltinStreaming
|
|
34
|
+
>,
|
|
27
35
|
[GroupManagementManifest.identifier]: GroupManagementStreamings as Record<
|
|
28
36
|
string,
|
|
29
37
|
BuiltinStreaming
|