refactor(workflow-file): phase1 migrate workflow file deps with compatibility bridge

Implement phase 1 of the file module migration by moving workflow-facing file primitives to core.workflow.file while keeping core.file as a temporary compatibility layer.

What this commit changes
- Add core.workflow.file package (constants/enums/models/helpers/file_manager/tool_file_parser).
- Add protocol-based runtime binding in core.workflow.file.runtime and core.workflow.file.protocols.
- Add application adapter core.app.workflow.file_runtime and bind runtime in extensions.ext_storage.init_app.
- Bind runtime in tests via tests/conftest.py.
- Migrate workflow-only imports from core.file.* to core.workflow.file.* across workflow runtime/nodes/entry/encoder and workflow node factory.
- Update workflow unit tests to patch/import the new workflow file namespace.
- Remove workflow-external-imports ignore_imports entries related to core.file from .importlinter.

Compatibility guarantee for phase split
- Keep core.file import path available in this phase by replacing core/file/*.py with forwarding bridge modules that re-export core.workflow.file symbols.
- Preserve runtime behavior and isinstance(File) identity consistency while non-workflow modules are still on legacy import paths.

Notes
- This commit intentionally does not remove core.file. Full repository replacement and bridge removal are handled in phase 2.
This commit is contained in:
WH-2099
2026-02-11 14:58:39 +08:00
parent f233e2036f
commit c56d650e83
55 changed files with 783 additions and 571 deletions

8
api/tests/conftest.py Normal file
View File

@ -0,0 +1,8 @@
import pytest
from core.app.workflow.file_runtime import bind_dify_workflow_file_runtime
@pytest.fixture(autouse=True)
def _bind_workflow_file_runtime() -> None:
bind_dify_workflow_file_runtime()

View File

@ -6,10 +6,10 @@ import httpx
import pytest
from sqlalchemy import Engine
from core.file import FileTransferMethod, FileType, models
from core.helper import ssrf_proxy
from core.tools import signature
from core.tools.tool_file_manager import ToolFileManager
from core.workflow.file import FileTransferMethod, FileType, models
from core.workflow.nodes.llm.file_saver import (
FileSaverImpl,
_extract_content_type_and_extension,

View File

@ -8,7 +8,6 @@ import pytest
from core.app.entities.app_invoke_entities import InvokeFrom, ModelConfigWithCredentialsEntity
from core.entities.provider_configuration import ProviderConfiguration, ProviderModelBundle
from core.entities.provider_entities import CustomConfiguration, SystemConfiguration
from core.file import File, FileTransferMethod, FileType
from core.model_runtime.entities.common_entities import I18nObject
from core.model_runtime.entities.message_entities import (
ImagePromptMessageContent,
@ -21,6 +20,7 @@ from core.model_runtime.entities.model_entities import AIModelEntity, FetchFrom,
from core.model_runtime.model_providers.model_provider_factory import ModelProviderFactory
from core.variables import ArrayAnySegment, ArrayFileSegment, NoneSegment
from core.workflow.entities import GraphInitParams
from core.workflow.file import File, FileTransferMethod, FileType
from core.workflow.nodes.llm import llm_utils
from core.workflow.nodes.llm.entities import (
ContextConfig,

View File

@ -2,9 +2,9 @@ from collections.abc import Mapping, Sequence
from pydantic import BaseModel, Field
from core.file import File
from core.model_runtime.entities.message_entities import PromptMessage
from core.model_runtime.entities.model_entities import ModelFeature
from core.workflow.file import File
from core.workflow.nodes.llm.entities import LLMNodeChatModelMessage

View File

@ -6,12 +6,12 @@ import pytest
from docx.oxml.text.paragraph import CT_P
from core.app.entities.app_invoke_entities import InvokeFrom
from core.file import File, FileTransferMethod
from core.variables import ArrayFileSegment
from core.variables.segments import ArrayStringSegment
from core.variables.variables import StringVariable
from core.workflow.entities import GraphInitParams
from core.workflow.enums import NodeType, WorkflowNodeExecutionStatus
from core.workflow.file import File, FileTransferMethod
from core.workflow.node_events import NodeRunResult
from core.workflow.nodes.document_extractor import DocumentExtractorNode, DocumentExtractorNodeData
from core.workflow.nodes.document_extractor.node import (
@ -146,7 +146,7 @@ def test_run_extract_text(
mock_ssrf_proxy_get.return_value.content = file_content
mock_ssrf_proxy_get.return_value.raise_for_status = Mock()
monkeypatch.setattr("core.file.file_manager.download", mock_download)
monkeypatch.setattr("core.workflow.file.file_manager.download", mock_download)
monkeypatch.setattr("core.helper.ssrf_proxy.get", mock_ssrf_proxy_get)
if mime_type == "application/pdf":

View File

@ -6,10 +6,10 @@ import pytest
from core.app.entities.app_invoke_entities import InvokeFrom
from core.app.workflow.node_factory import DifyNodeFactory
from core.file import File, FileTransferMethod, FileType
from core.variables import ArrayFileSegment
from core.workflow.entities import GraphInitParams
from core.workflow.enums import WorkflowNodeExecutionStatus
from core.workflow.file import File, FileTransferMethod, FileType
from core.workflow.graph import Graph
from core.workflow.nodes.if_else.entities import IfElseNodeData
from core.workflow.nodes.if_else.if_else_node import IfElseNode

View File

@ -3,9 +3,9 @@ from unittest.mock import MagicMock
import pytest
from core.app.entities.app_invoke_entities import InvokeFrom
from core.file import File, FileTransferMethod, FileType
from core.variables import ArrayFileSegment
from core.workflow.enums import WorkflowNodeExecutionStatus
from core.workflow.file import File, FileTransferMethod, FileType
from core.workflow.nodes.list_operator.entities import (
ExtractConfig,
FilterBy,

View File

@ -8,12 +8,12 @@ from unittest.mock import MagicMock, patch
import pytest
from core.file import File, FileTransferMethod, FileType
from core.model_runtime.entities.llm_entities import LLMUsage
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.utils.message_transformer import ToolFileMessageTransformer
from core.variables.segments import ArrayFileSegment
from core.workflow.entities import GraphInitParams
from core.workflow.file import File, FileTransferMethod, FileType
from core.workflow.node_events import StreamChunkEvent, StreamCompletedEvent
from core.workflow.runtime import GraphRuntimeState, VariablePool
from core.workflow.system_variable import SystemVariable

View File

@ -3,10 +3,10 @@ from unittest.mock import patch
import pytest
from core.app.entities.app_invoke_entities import InvokeFrom
from core.file import File, FileTransferMethod, FileType
from core.variables import FileVariable, StringVariable
from core.workflow.entities.graph_init_params import GraphInitParams
from core.workflow.entities.workflow_node_execution import WorkflowNodeExecutionStatus
from core.workflow.file import File, FileTransferMethod, FileType
from core.workflow.nodes.trigger_webhook.entities import (
ContentType,
Method,

View File

@ -4,8 +4,8 @@ from typing import Any
import pytest
from pydantic import ValidationError
from core.file.enums import FileTransferMethod, FileType
from core.file.models import File
from core.workflow.file.enums import FileTransferMethod, FileType
from core.workflow.file.models import File
from core.workflow.system_variable import SystemVariable
# Test data constants for SystemVariable serialization tests

View File

@ -2,7 +2,7 @@ from typing import cast
import pytest
from core.file.models import File, FileTransferMethod, FileType
from core.workflow.file.models import File, FileTransferMethod, FileType
from core.workflow.system_variable import SystemVariable, SystemVariableReadOnlyView

View File

@ -3,7 +3,6 @@ from collections import defaultdict
import pytest
from core.file import File, FileTransferMethod, FileType
from core.variables import FileSegment, StringSegment
from core.variables.segments import (
ArrayAnySegment,
@ -27,6 +26,7 @@ from core.variables.variables import (
Variable,
)
from core.workflow.constants import CONVERSATION_VARIABLE_NODE_ID, ENVIRONMENT_VARIABLE_NODE_ID, SYSTEM_VARIABLE_NODE_ID
from core.workflow.file import File, FileTransferMethod, FileType
from core.workflow.runtime import VariablePool
from core.workflow.system_variable import SystemVariable
from factories.variable_factory import build_segment, segment_to_variable

View File

@ -3,14 +3,14 @@ from types import SimpleNamespace
import pytest
from configs import dify_config
from core.file.enums import FileType
from core.file.models import File, FileTransferMethod
from core.helper.code_executor.code_executor import CodeLanguage
from core.variables.variables import StringVariable
from core.workflow.constants import (
CONVERSATION_VARIABLE_NODE_ID,
ENVIRONMENT_VARIABLE_NODE_ID,
)
from core.workflow.file.enums import FileType
from core.workflow.file.models import File, FileTransferMethod
from core.workflow.nodes.code.code_node import CodeNode
from core.workflow.nodes.code.limits import CodeNodeLimits
from core.workflow.runtime import VariablePool