From af579ec23d9eab7c1ed4521e0122d5b54ff8399f Mon Sep 17 00:00:00 2001 From: Joel Date: Thu, 25 Jun 2026 18:39:27 +0800 Subject: [PATCH] feat: handle chat files --- .../agent-orchestrate-drawer-panel.tsx | 2 +- .../configure/__tests__/page.spec.tsx | 8 +- .../preview/__tests__/header.spec.tsx | 16 ++- .../configure/components/preview/header.tsx | 10 +- .../preview/working-directory-panel.tsx | 124 ++++++++++++++++++ .../agent-v2/agent-detail/configure/page.tsx | 16 ++- web/i18n/ar-TN/agent-v-2.json | 4 + web/i18n/de-DE/agent-v-2.json | 4 + web/i18n/en-US/agent-v-2.json | 4 + web/i18n/es-ES/agent-v-2.json | 4 + web/i18n/fa-IR/agent-v-2.json | 4 + web/i18n/fr-FR/agent-v-2.json | 4 + web/i18n/hi-IN/agent-v-2.json | 4 + web/i18n/id-ID/agent-v-2.json | 4 + web/i18n/it-IT/agent-v-2.json | 4 + web/i18n/ja-JP/agent-v-2.json | 4 + web/i18n/ko-KR/agent-v-2.json | 4 + web/i18n/nl-NL/agent-v-2.json | 4 + web/i18n/pl-PL/agent-v-2.json | 4 + web/i18n/pt-BR/agent-v-2.json | 4 + web/i18n/ro-RO/agent-v-2.json | 4 + web/i18n/ru-RU/agent-v-2.json | 4 + web/i18n/sl-SI/agent-v-2.json | 4 + web/i18n/th-TH/agent-v-2.json | 4 + web/i18n/tr-TR/agent-v-2.json | 4 + web/i18n/uk-UA/agent-v-2.json | 4 + web/i18n/vi-VN/agent-v-2.json | 4 + web/i18n/zh-Hans/agent-v-2.json | 4 + web/i18n/zh-Hant/agent-v-2.json | 4 + 29 files changed, 254 insertions(+), 14 deletions(-) create mode 100644 web/features/agent-v2/agent-detail/configure/components/preview/working-directory-panel.tsx diff --git a/web/app/components/workflow/nodes/agent-v2/components/agent-orchestrate-drawer-panel.tsx b/web/app/components/workflow/nodes/agent-v2/components/agent-orchestrate-drawer-panel.tsx index c2350b7009d..292ddc9558a 100644 --- a/web/app/components/workflow/nodes/agent-v2/components/agent-orchestrate-drawer-panel.tsx +++ b/web/app/components/workflow/nodes/agent-v2/components/agent-orchestrate-drawer-panel.tsx @@ -234,7 +234,7 @@ function WorkflowInlineAgentConfigureWorkspaceContent({ isChatFeaturesOpen={false} onModeChange={() => undefined} onToggleChatFeatures={() => undefined} - onOpenVersions={() => undefined} + onOpenWorkingDirectory={() => undefined} onRefresh={() => { setConversationId(null) setClearChatList(true) diff --git a/web/features/agent-v2/agent-detail/configure/__tests__/page.spec.tsx b/web/features/agent-v2/agent-detail/configure/__tests__/page.spec.tsx index f22c183fdb8..6e1b3429ee2 100644 --- a/web/features/agent-v2/agent-detail/configure/__tests__/page.spec.tsx +++ b/web/features/agent-v2/agent-detail/configure/__tests__/page.spec.tsx @@ -167,6 +167,7 @@ vi.mock('../components/orchestrate', () => ({ AgentOrchestratePanel: (props: { bottomBar?: ReactNode isBuildDraftActive?: boolean + onOpenVersions?: () => void readOnly?: boolean showPublishBar?: boolean }) => ( @@ -174,6 +175,7 @@ vi.mock('../components/orchestrate', () => ({ {`buildDraft:${props.isBuildDraftActive ? 'yes' : 'no'}`} {`readonly:${props.readOnly ? 'yes' : 'no'}`} {`publish:${props.showPublishBar ? 'yes' : 'no'}`} + {props.bottomBar} ), @@ -243,7 +245,7 @@ vi.mock('../components/preview/header', () => ({ mode: 'build' | 'preview' previewEnabled: boolean onModeChange: (mode: 'build' | 'preview') => void - onOpenVersions: () => void + onOpenWorkingDirectory: () => void onRefresh: () => void }) => (
@@ -254,8 +256,8 @@ vi.mock('../components/preview/header', () => ({ - @@ -152,7 +152,7 @@ export function AgentPreviewHeader({ )} - {trailingAction && ( + {trailingAction != null && ( <> {trailingAction} diff --git a/web/features/agent-v2/agent-detail/configure/components/preview/working-directory-panel.tsx b/web/features/agent-v2/agent-detail/configure/components/preview/working-directory-panel.tsx new file mode 100644 index 00000000000..6479911eee8 --- /dev/null +++ b/web/features/agent-v2/agent-detail/configure/components/preview/working-directory-panel.tsx @@ -0,0 +1,124 @@ +'use client' + +import type { AgentFileNode } from '@/features/agent-v2/agent-composer/form-state' +import { + Drawer, + DrawerBackdrop, + DrawerCloseButton, + DrawerContent, + DrawerDescription, + DrawerPopup, + DrawerPortal, + DrawerTitle, + DrawerViewport, +} from '@langgenius/dify-ui/drawer' +import { FileTreeFile } from '@langgenius/dify-ui/file-tree' +import { useTranslation } from 'react-i18next' +import { AgentFileTree } from '../orchestrate/files/tree' + +type AgentWorkingDirectoryPanelProps = { + onOpenChange: (open: boolean) => void + open: boolean +} + +const workingDirectoryFiles: AgentFileNode[] = [ + { + id: 'working-directory/_index.json', + name: '_index.json', + icon: 'json', + driveKey: 'working-directory/_index.json', + }, + { + id: 'working-directory/web-game', + name: 'web-game', + icon: 'folder', + driveKey: 'working-directory/web-game', + children: [ + { + id: 'working-directory/web-game/public', + name: 'public', + icon: 'folder', + driveKey: 'working-directory/web-game/public', + }, + { + id: 'working-directory/web-game/assets', + name: 'assets', + icon: 'folder', + driveKey: 'working-directory/web-game/assets', + }, + { + id: 'working-directory/web-game/src', + name: 'src', + icon: 'folder', + driveKey: 'working-directory/web-game/src', + }, + { + id: 'working-directory/web-game/styles', + name: 'styles', + icon: 'folder', + driveKey: 'working-directory/web-game/styles', + }, + { + id: 'working-directory/web-game/README.md', + name: 'README.md', + icon: 'markdown', + driveKey: 'working-directory/web-game/README.md', + }, + ], + }, +] + +const selectedWorkingDirectoryFileId = 'working-directory/web-game/README.md' + +export function AgentWorkingDirectoryPanel({ + onOpenChange, + open, +}: AgentWorkingDirectoryPanelProps) { + const { t } = useTranslation('agentV2') + const { t: tCommon } = useTranslation('common') + + return ( + + + + + + +
+
+ + {t('agentDetail.configure.workingDirectory.title')} + + + {t('agentDetail.configure.workingDirectory.description')} + +
+ +
+ ( + + {children} + {selected && ( + + )} + + )} + /> +
+
+
+
+
+ ) +} diff --git a/web/features/agent-v2/agent-detail/configure/page.tsx b/web/features/agent-v2/agent-detail/configure/page.tsx index d7a58105d52..310dcce39f5 100644 --- a/web/features/agent-v2/agent-detail/configure/page.tsx +++ b/web/features/agent-v2/agent-detail/configure/page.tsx @@ -15,6 +15,7 @@ import { AgentChatFeaturesPanel } from './components/preview/chat-features-panel import { AgentPreviewHeader } from './components/preview/header' import { AgentPreviewChat } from './components/preview/preview-chat' import { AgentPreviewVersionsPanel } from './components/preview/versions-panel' +import { AgentWorkingDirectoryPanel } from './components/preview/working-directory-panel' import { AgentConfigurePreviewSurface, AgentConfigureWorkspace } from './components/workspace' import { useAgentConfigureData, useAgentConfigureModelOptions, useAgentPreviewSoulConfig } from './hooks' import { useAgentConfigureBuildDraftActions, useAgentConfigureBuildDraftData } from './use-agent-configure-build-draft' @@ -82,6 +83,7 @@ function AgentConfigurePageLoadedContent({ const queryClient = useQueryClient() const [showChatFeatures, setShowChatFeatures] = useState(false) const [showPreviewVersions, setShowPreviewVersions] = useState(false) + const [showWorkingDirectory, setShowWorkingDirectory] = useState(false) const [clearPreviewChat, setClearPreviewChat] = useState(false) const [rightPanelMode, setRightPanelMode] = useState('build') const [hideBuildDraftBarUntilRefresh, setHideBuildDraftBarUntilRefresh] = useState(false) @@ -258,7 +260,10 @@ function AgentConfigurePageLoadedContent({ : undefined} onSelectModel={setConfigureModel} onPublish={publishDraft} - onOpenVersions={() => setShowPreviewVersions(true)} + onOpenVersions={() => { + setShowWorkingDirectory(false) + setShowPreviewVersions(true) + }} onExitVersions={() => selectVersion(null)} /> )} @@ -272,7 +277,10 @@ function AgentConfigurePageLoadedContent({ isChatFeaturesOpen={showChatFeatures} onModeChange={setRightPanelMode} onToggleChatFeatures={() => setShowChatFeatures(open => !open)} - onOpenVersions={() => setShowPreviewVersions(true)} + onOpenWorkingDirectory={() => { + setShowPreviewVersions(false) + setShowWorkingDirectory(true) + }} onRefresh={restartCurrentChat} refreshDisabled={isRefreshingDebugConversation || buildDraftActions.isDiscardingBuildDraft} /> @@ -315,6 +323,10 @@ function AgentConfigurePageLoadedContent({ onClose={() => setShowPreviewVersions(false)} /> )} +