Skip to content

Commit

Permalink
Merge branch 'feat/support-file-download-in-workflow' into deploy/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
JzoNgKVO committed Dec 4, 2024
2 parents 36940ec + 323a6f8 commit 16e08fc
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 28 deletions.
10 changes: 1 addition & 9 deletions api/core/workflow/nodes/http_request/node.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import logging
from collections.abc import Mapping, Sequence
from mimetypes import guess_extension
from os import path
from typing import Any

from configs import dify_config
from core.file import File, FileTransferMethod, FileType
from core.file import File, FileTransferMethod
from core.tools.tool_file_manager import ToolFileManager
from core.workflow.entities.node_entities import NodeRunResult
from core.workflow.entities.variable_entities import VariableSelector
Expand Down Expand Up @@ -166,11 +164,6 @@ def extract_files(self, url: str, response: Response) -> list[File]:
content = response.content

if is_file and content_type:
# extract filename from url
filename = path.basename(url)
# extract extension if possible
extension = guess_extension(content_type) or ".bin"

tool_file = ToolFileManager.create_file_by_raw(
user_id=self.user_id,
tenant_id=self.tenant_id,
Expand All @@ -181,7 +174,6 @@ def extract_files(self, url: str, response: Response) -> list[File]:

mapping = {
"tool_file_id": tool_file.id,
"type": FileType.IMAGE.value,
"transfer_method": FileTransferMethod.TOOL_FILE.value,
}
file = file_factory.build_from_mapping(
Expand Down
2 changes: 1 addition & 1 deletion web/app/components/app/text-generate/item/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ const GenerationItem: FC<IGenerationItemProps> = ({
</SimpleBtn>
)
}
{(currentTab === 'RESULT' || !isWorkflow) && (
{((currentTab === 'RESULT' && workflowProcessData?.resultText) || !isWorkflow) && (
<SimpleBtn
isDisabled={isError || !messageId}
className={cn(isMobile && '!px-1.5', 'space-x-1')}
Expand Down
8 changes: 4 additions & 4 deletions web/app/components/app/text-generate/item/result-tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ const ResultTab = ({
onCurrentTabChange(tab)
}
useEffect(() => {
if (data?.resultText)
if (data?.resultText || !!data?.files?.length)
switchTab('RESULT')
else
switchTab('DETAIL')
}, [data?.resultText])
}, [data?.files?.length, data?.resultText])

return (
<div className='grow relative flex flex-col'>
{data?.resultText && (
{(data?.resultText || !!data?.files?.length) && (
<div className='shrink-0 flex items-center mb-2 border-b-[0.5px] border-[rgba(0,0,0,0.05)]'>
<div
className={cn(
Expand All @@ -56,7 +56,7 @@ const ResultTab = ({
<div className={cn('grow bg-white')}>
{currentTab === 'RESULT' && (
<>
<Markdown content={data?.resultText || ''} />
{data?.resultText && <Markdown content={data?.resultText || ''} />}
{!!data?.files?.length && (
<FileList
files={data?.files}
Expand Down
9 changes: 5 additions & 4 deletions web/app/components/base/file-uploader/file-list-in-log.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RiArrowRightSLine } from '@remixicon/react'
import FileImageRender from './file-image-render'
import FileTypeIcon from './file-type-icon'
Expand All @@ -16,18 +17,18 @@ type Props = {
}

const FileListInLog = ({ fileList }: Props) => {
const { t } = useTranslation()
const [expanded, setExpanded] = useState(false)

if (!fileList.length)
return null
return (
<div className={cn('border-t border-divider-subtle px-3 py-2', expanded && 'py-3')}>
<div className='flex justify-between gap-1'>
{expanded && (
<div></div>
<div className='text-text-tertiary system-xs-medium-uppercase'>{t('appLog.runDetail.fileListLabel')}</div>
)}
{!expanded && (
<div className='flex'>
<div className='flex gap-1'>
{fileList.map((file) => {
const { id, name, type, supportFileType, base64Url, url } = file
const isImageFile = supportFileType === SupportUploadFileTypes.image
Expand Down Expand Up @@ -63,7 +64,7 @@ const FileListInLog = ({ fileList }: Props) => {
</div>
)}
<div className='flex items-center gap-1 cursor-pointer' onClick={() => setExpanded(!expanded)}>
{!expanded && <div className='text-text-tertiary system-xs-medium-uppercase'>DETAIL</div>}
{!expanded && <div className='text-text-tertiary system-xs-medium-uppercase'>{t('appLog.runDetail.fileListDetail')}</div>}
<RiArrowRightSLine className={cn('w-4 h-4 text-text-tertiary', expanded && 'rotate-90')} />
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const FileImageItem = ({
className='absolute bottom-0.5 right-0.5 flex items-center justify-center w-6 h-6 rounded-lg bg-components-actionbar-bg shadow-md'
onClick={(e) => {
e.stopPropagation()
downloadFile(url || '', name)
downloadFile(url || base64Url || '', name)
}}
>
<RiDownloadLine className='w-4 h-4 text-text-tertiary' />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const FileItem = ({
}
</div>
{
showDownloadAction && (
showDownloadAction && url && (
<ActionButton
size='m'
className='hidden group-hover/file-item:flex absolute -right-1 -top-1'
Expand Down
2 changes: 1 addition & 1 deletion web/app/components/base/file-uploader/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export const getFilesInLogs = (rawData: any) => {
if (typeof rawData[key] === 'object' || Array.isArray(rawData[key]))
return rawData[key]
return undefined
}).filter(Boolean)).filter(item => item?.model_identity === '__dify__file__')
}).filter(Boolean)).filter(item => item?.dify_model_identity === '__dify__file__')
return getProcessedFilesFromResponse(originalFiles)
}

Expand Down
2 changes: 1 addition & 1 deletion web/app/components/workflow/panel/workflow-preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const WorkflowPreview = () => {
}, [showDebugAndPreviewPanel, showInputsPanel])

useEffect(() => {
if ((workflowRunningData?.result.status === WorkflowRunningStatus.Succeeded || workflowRunningData?.result.status === WorkflowRunningStatus.Failed) && !workflowRunningData.resultText)
if ((workflowRunningData?.result.status === WorkflowRunningStatus.Succeeded || workflowRunningData?.result.status === WorkflowRunningStatus.Failed) && !workflowRunningData.resultText && !workflowRunningData.result.files?.length)
switchTab('DETAIL')
}, [workflowRunningData])

Expand Down
43 changes: 40 additions & 3 deletions web/app/components/workflow/run/output-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
'use client'
import type { FC } from 'react'
import { useMemo } from 'react'
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
import { Markdown } from '@/app/components/base/markdown'
import LoadingAnim from '@/app/components/base/chat/chat/loading-anim'
import { FileList } from '@/app/components/base/file-uploader'
import StatusContainer from '@/app/components/workflow/run/status-container'

type OutputPanelProps = {
Expand All @@ -19,6 +21,30 @@ const OutputPanel: FC<OutputPanelProps> = ({
error,
height,
}) => {
const isTextOutput = useMemo(() => {
return outputs && Object.keys(outputs).length === 1 && typeof outputs[Object.keys(outputs)[0]] === 'string'
}, [outputs])

const fileList = useMemo(() => {
const fileList: any[] = []
if (!outputs)
return fileList
if (Object.keys(outputs).length > 1)
return fileList
for (const key in outputs) {
if (Array.isArray(outputs[key])) {
outputs[key].map((output: any) => {
if (output.dify_model_identity === '__dify__file__')
fileList.push(output)
return null
})
}
else if (outputs[key].dify_model_identity === '__dify__file__') {
fileList.push(outputs[key])
}
}
return fileList
}, [outputs])
return (
<div className='py-2'>
{isRunning && (
Expand All @@ -36,20 +62,31 @@ const OutputPanel: FC<OutputPanelProps> = ({
<Markdown content='No Output' />
</div>
)}
{outputs && Object.keys(outputs).length === 1 && (
{isTextOutput && (
<div className='px-4 py-2'>
<Markdown content={outputs[Object.keys(outputs)[0]] || ''} />
</div>
)}
{fileList.length > 0 && (
<div className='px-4 py-2'>
<FileList
files={fileList}
showDeleteAction={false}
showDownloadAction
canPreview
/>
</div>
)}
{outputs && Object.keys(outputs).length > 1 && height! > 0 && (
<div className='px-4 py-2 flex flex-col gap-2'>
<div className='flex flex-col gap-2'>
<CodeEditor
showFileList
readOnly
title={<div></div>}
language={CodeLanguage.json}
value={outputs}
isJSONStringifyBeauty
height={height}
height={height ? height - 50 - 16 : undefined}
/>
</div>
)}
Expand Down
6 changes: 3 additions & 3 deletions web/app/components/workflow/run/result-text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const ResultText: FC<ResultTextProps> = ({
</StatusContainer>
</div>
)}
{!isRunning && !outputs && !error && (
{!isRunning && !outputs && !error && !allFiles?.length && (
<div className='mt-[120px] px-4 py-2 flex flex-col items-center text-[13px] leading-[18px] text-gray-500'>
<ImageIndentLeft className='w-6 h-6 text-gray-400' />
<div className='mr-2'>{t('runLog.resultEmpty.title')}</div>
Expand All @@ -49,9 +49,9 @@ const ResultText: FC<ResultTextProps> = ({
</div>
</div>
)}
{outputs && (
{(outputs || !!allFiles?.length) && (
<div className='px-4 py-2'>
<Markdown content={outputs} />
{outputs && <Markdown content={outputs} />}
{!!allFiles?.length && (
<FileList
files={allFiles}
Expand Down
2 changes: 2 additions & 0 deletions web/i18n/en-US/app-log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ const translation = {
runDetail: {
title: 'Conversation Log',
workflowTitle: 'Log Detail',
fileListLabel: 'File List',
fileListDetail: 'Detail',
},
promptLog: 'Prompt Log',
agentLog: 'Agent Log',
Expand Down
2 changes: 2 additions & 0 deletions web/i18n/zh-Hans/app-log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ const translation = {
runDetail: {
title: '对话日志',
workflowTitle: '日志详情',
fileListLabel: '文件列表',
fileListDetail: '详情',
},
promptLog: 'Prompt 日志',
agentLog: 'Agent 日志',
Expand Down

0 comments on commit 16e08fc

Please sign in to comment.