fix: resolve import migrations and test failures after segment 3 merge

- Migrate core.model_runtime -> dify_graph.model_runtime across 20+ files
- Migrate core.workflow.file -> dify_graph.file across 15+ files
- Migrate core.workflow.enums -> dify_graph.enums in service files
- Fix SandboxContext phantom import in dify_graph/context/__init__.py
- Fix core.app.workflow.node_factory -> core.workflow.node_factory
- Fix toast import paths (useToastContext from toast/context)
- Fix app-info.tsx import paths for relocated app-operations
- Fix 15 frontend test files for API changes, missing QueryClientProvider,
  i18n key renames, and component behavior changes

Made-with: Cursor
This commit is contained in:
Novice
2026-03-23 10:31:11 +08:00
parent 94b01f6821
commit 6b75188ddc
58 changed files with 242 additions and 172 deletions

View File

@ -4,7 +4,7 @@ from decimal import Decimal
from unittest.mock import MagicMock
import pytest
from core.model_runtime.entities.llm_entities import LLMUsage
from dify_graph.model_runtime.entities.llm_entities import LLMUsage
from core.agent.entities import AgentLog, ExecutionContext
from core.agent.patterns.base import AgentPattern

View File

@ -4,8 +4,8 @@ from decimal import Decimal
from unittest.mock import MagicMock
import pytest
from core.model_runtime.entities.llm_entities import LLMUsage
from core.model_runtime.entities.message_entities import (
from dify_graph.model_runtime.entities.llm_entities import LLMUsage
from dify_graph.model_runtime.entities.message_entities import (
PromptMessageTool,
SystemPromptMessage,
UserPromptMessage,
@ -312,7 +312,7 @@ class TestPromptMessageHandling:
def test_assistant_message_with_tool_calls(self, mock_model_instance, mock_context, mock_tool):
"""Test that assistant messages can contain tool calls."""
from core.model_runtime.entities.message_entities import AssistantPromptMessage
from dify_graph.model_runtime.entities.message_entities import AssistantPromptMessage
tool_call = AssistantPromptMessage.ToolCall(
id="call_123",

View File

@ -6,7 +6,7 @@ import pytest
from core.agent.entities import ExecutionContext
from core.agent.patterns.react import ReActStrategy
from core.model_runtime.entities import SystemPromptMessage, UserPromptMessage
from dify_graph.model_runtime.entities import SystemPromptMessage, UserPromptMessage
@pytest.fixture
@ -33,7 +33,7 @@ def mock_context():
@pytest.fixture
def mock_tool():
"""Create a mock tool."""
from core.model_runtime.entities.message_entities import PromptMessageTool
from dify_graph.model_runtime.entities.message_entities import PromptMessageTool
tool = MagicMock()
tool.entity.identity.name = "test_tool"
@ -158,7 +158,7 @@ class TestBuildPromptWithReactFormat:
def test_scratchpad_appended_as_assistant_message(self, mock_model_instance, mock_context):
"""Test that agent scratchpad is appended as AssistantPromptMessage."""
from core.agent.entities import AgentScratchpadUnit
from core.model_runtime.entities import AssistantPromptMessage
from dify_graph.model_runtime.entities import AssistantPromptMessage
strategy = ReActStrategy(
model_instance=mock_model_instance,

View File

@ -3,7 +3,7 @@
from unittest.mock import MagicMock
import pytest
from core.model_runtime.entities.model_entities import ModelFeature
from dify_graph.model_runtime.entities.model_entities import ModelFeature
from core.agent.entities import AgentEntity, ExecutionContext
from core.agent.patterns.function_call import FunctionCallStrategy

View File

@ -4,10 +4,10 @@ from decimal import Decimal
from unittest.mock import MagicMock, patch
import pytest
from core.model_runtime.entities.llm_entities import LLMUsage
from dify_graph.model_runtime.entities.llm_entities import LLMUsage
from core.agent.entities import AgentEntity, AgentLog, AgentPromptEntity, AgentResult
from core.model_runtime.entities import SystemPromptMessage, UserPromptMessage
from dify_graph.model_runtime.entities import SystemPromptMessage, UserPromptMessage
class TestOrganizePromptMessages:
@ -184,7 +184,7 @@ class TestClearUserPromptImageMessages:
def test_original_messages_not_modified(self, mock_runner):
"""Test that original messages are not modified (deep copy)."""
from core.model_runtime.entities.message_entities import (
from dify_graph.model_runtime.entities.message_entities import (
ImagePromptMessageContent,
TextPromptMessageContent,
)
@ -365,13 +365,13 @@ class TestOrganizeUserQuery:
def test_query_with_files(self, mock_runner):
"""Test organizing a query with files."""
from core.workflow.file.models import File
from dify_graph.file.models import File
mock_file = MagicMock(spec=File)
mock_runner.files = [mock_file]
with patch("core.agent.agent_app_runner.file_manager") as mock_fm:
from core.model_runtime.entities.message_entities import ImagePromptMessageContent
from dify_graph.model_runtime.entities.message_entities import ImagePromptMessageContent
mock_fm.to_prompt_message_content.return_value = ImagePromptMessageContent(
data="http://example.com/image.jpg",

View File

@ -2,8 +2,8 @@ from unittest.mock import MagicMock
from core.app.apps.base_app_queue_manager import PublishFrom
from core.app.apps.workflow_app_runner import WorkflowBasedAppRunner
from core.workflow.graph_events import NodeRunStreamChunkEvent
from core.workflow.nodes import NodeType
from dify_graph.graph_events import NodeRunStreamChunkEvent
from dify_graph.enums import NodeType
class DummyQueueManager:

View File

@ -2,14 +2,14 @@
from unittest.mock import patch
from core.model_runtime.entities.message_entities import ImagePromptMessageContent
from core.workflow.file.file_manager import (
from dify_graph.model_runtime.entities.message_entities import ImagePromptMessageContent
from dify_graph.file.file_manager import (
_encode_file_ref,
restore_multimodal_content,
to_prompt_message_content,
)
from core.workflow.file import File, FileTransferMethod, FileType
from dify_graph.file import File, FileTransferMethod, FileType
class TestEncodeFileRef:
@ -52,8 +52,8 @@ class TestEncodeFileRef:
class TestToPromptMessageContent:
"""Tests for to_prompt_message_content function with file_ref field."""
@patch("core.workflow.file.file_manager.dify_config")
@patch("core.workflow.file.file_manager._get_encoded_string")
@patch("dify_graph.file.file_manager.dify_config")
@patch("dify_graph.file.file_manager._get_encoded_string")
def test_includes_file_ref(self, mock_get_encoded, mock_config):
"""Generated content should include file_ref field."""
mock_config.MULTIMODAL_SEND_FORMAT = "base64"
@ -121,9 +121,9 @@ class TestRestoreMultimodalContent:
assert result.url == "https://example.com/image.png"
@patch("core.workflow.file.file_manager.dify_config")
@patch("core.workflow.file.file_manager._build_file_from_ref")
@patch("core.workflow.file.file_manager._to_url")
@patch("dify_graph.file.file_manager.dify_config")
@patch("dify_graph.file.file_manager._build_file_from_ref")
@patch("dify_graph.file.file_manager._to_url")
def test_restores_url_from_file_ref(self, mock_to_url, mock_build_file, mock_config):
"""Content should be restored from file_ref when url is empty (url mode)."""
mock_config.MULTIMODAL_SEND_FORMAT = "url"
@ -144,9 +144,9 @@ class TestRestoreMultimodalContent:
assert result.url == "https://restored-url.com/image.png"
mock_build_file.assert_called_once()
@patch("core.workflow.file.file_manager.dify_config")
@patch("core.workflow.file.file_manager._build_file_from_ref")
@patch("core.workflow.file.file_manager._get_encoded_string")
@patch("dify_graph.file.file_manager.dify_config")
@patch("dify_graph.file.file_manager._build_file_from_ref")
@patch("dify_graph.file.file_manager._get_encoded_string")
def test_restores_base64_from_file_ref(self, mock_get_encoded, mock_build_file, mock_config):
"""Content should be restored as base64 when in base64 mode."""
mock_config.MULTIMODAL_SEND_FORMAT = "base64"

View File

@ -3,7 +3,7 @@ Unit tests for sandbox file path detection and conversion.
"""
import pytest
from core.workflow.variables.segments import ArrayFileSegment, FileSegment
from dify_graph.variables.segments import ArrayFileSegment, FileSegment
from core.llm_generator.output_parser.file_ref import (
FILE_PATH_DESCRIPTION_SUFFIX,
@ -13,7 +13,7 @@ from core.llm_generator.output_parser.file_ref import (
detect_file_path_fields,
is_file_path_property,
)
from core.workflow.file import File, FileTransferMethod, FileType
from dify_graph.file import File, FileTransferMethod, FileType
def _build_file(file_id: str) -> File:

View File

@ -2,21 +2,21 @@
from unittest.mock import MagicMock
from core.workflow.entities.tool_entities import ToolResultStatus
from core.workflow.enums import NodeType
from core.workflow.graph.graph import Graph
from core.workflow.graph_engine.response_coordinator.coordinator import ResponseStreamCoordinator
from core.workflow.graph_engine.response_coordinator.session import ResponseSession
from core.workflow.nodes.base.entities import BaseNodeData
from core.workflow.nodes.base.template import Template, VariableSegment
from dify_graph.entities.tool_entities import ToolResultStatus
from dify_graph.enums import NodeType
from dify_graph.graph.graph import Graph
from dify_graph.graph_engine.response_coordinator.coordinator import ResponseStreamCoordinator
from dify_graph.graph_engine.response_coordinator.session import ResponseSession
from dify_graph.nodes.base.entities import BaseNodeData
from dify_graph.nodes.base.template import Template, VariableSegment
from core.workflow.graph_events import (
from dify_graph.graph_events import (
ChunkType,
NodeRunStreamChunkEvent,
ToolCall,
ToolResult,
)
from core.workflow.runtime import VariablePool
from dify_graph.runtime import VariablePool
class TestResponseCoordinatorObjectStreaming:

View File

@ -1,7 +1,7 @@
"""Tests for StreamChunkEvent and its subclasses."""
from core.workflow.entities import ToolCall, ToolResult, ToolResultStatus
from core.workflow.node_events import (
from dify_graph.entities import ToolCall, ToolResult, ToolResultStatus
from dify_graph.node_events import (
ChunkType,
StreamChunkEvent,
ThoughtChunkEvent,

View File

@ -4,8 +4,8 @@ from io import BytesIO
from typing import Any
from unittest.mock import MagicMock
from core.workflow.enums import WorkflowNodeExecutionStatus
from core.workflow.system_variable import SystemVariable
from dify_graph.enums import WorkflowNodeExecutionStatus
from dify_graph.system_variable import SystemVariable
from core.entities.provider_entities import BasicProviderConfig
from core.virtual_environment.__base.entities import (
@ -19,9 +19,10 @@ from core.virtual_environment.__base.entities import (
from core.virtual_environment.__base.virtual_environment import VirtualEnvironment
from core.virtual_environment.channel.queue_transport import QueueTransportReadCloser
from core.virtual_environment.channel.transport import NopTransportWriteCloser
from core.workflow.entities import GraphInitParams
from dify_graph.entities import GraphInitParams
from dify_graph.entities.graph_init_params import DIFY_RUN_CONTEXT_KEY
from core.workflow.nodes.command.node import CommandNode
from core.workflow.runtime import GraphRuntimeState, VariablePool
from dify_graph.runtime import GraphRuntimeState, VariablePool
class FakeVirtualEnvironment(VirtualEnvironment):
@ -138,14 +139,18 @@ def _make_node(
variable_pool = VariablePool(system_variables=system_variables, user_inputs={})
runtime_state = GraphRuntimeState(variable_pool=variable_pool, start_at=time.perf_counter())
init_params = GraphInitParams(
tenant_id="t",
app_id="a",
workflow_id="w",
graph_config={},
user_id="u",
user_from="account",
invoke_from="debugger",
call_depth=0,
run_context={
DIFY_RUN_CONTEXT_KEY: {
"tenant_id": "t",
"app_id": "a",
"user_id": "u",
"user_from": "account",
"invoke_from": "debugger",
}
},
)
if vm is not None:

View File

@ -3,12 +3,12 @@
import string
from unittest.mock import patch
from core.model_runtime.entities.message_entities import (
from dify_graph.model_runtime.entities.message_entities import (
ImagePromptMessageContent,
TextPromptMessageContent,
UserPromptMessage,
)
from core.workflow.nodes.llm.llm_utils import (
from dify_graph.nodes.llm.llm_utils import (
_truncate_multimodal_content,
build_context,
restore_multimodal_content_in_messages,
@ -100,7 +100,7 @@ class TestBuildContext:
def test_excludes_system_messages(self):
"""System messages should be excluded from context."""
from core.model_runtime.entities.message_entities import SystemPromptMessage
from dify_graph.model_runtime.entities.message_entities import SystemPromptMessage
messages = [
SystemPromptMessage(content="You are a helpful assistant."),
@ -125,12 +125,12 @@ class TestBuildContext:
def test_builds_context_with_tool_calls_from_generation_data(self):
"""Should reconstruct full conversation including tool calls when generation_data is provided."""
from core.model_runtime.entities.llm_entities import LLMUsage
from core.model_runtime.entities.message_entities import (
from dify_graph.model_runtime.entities.llm_entities import LLMUsage
from dify_graph.model_runtime.entities.message_entities import (
AssistantPromptMessage,
ToolPromptMessage,
)
from core.workflow.nodes.llm.entities import (
from dify_graph.nodes.llm.entities import (
LLMGenerationData,
LLMTraceSegment,
ModelTraceSegment,
@ -199,12 +199,12 @@ class TestBuildContext:
def test_builds_context_with_multiple_tool_calls(self):
"""Should handle multiple tool calls in a single conversation."""
from core.model_runtime.entities.llm_entities import LLMUsage
from core.model_runtime.entities.message_entities import (
from dify_graph.model_runtime.entities.llm_entities import LLMUsage
from dify_graph.model_runtime.entities.message_entities import (
AssistantPromptMessage,
ToolPromptMessage,
)
from core.workflow.nodes.llm.entities import (
from dify_graph.nodes.llm.entities import (
LLMGenerationData,
LLMTraceSegment,
ModelTraceSegment,
@ -291,8 +291,8 @@ class TestBuildContext:
def test_builds_context_with_empty_trace(self):
"""Should fallback to simple context when trace is empty."""
from core.model_runtime.entities.llm_entities import LLMUsage
from core.workflow.nodes.llm.entities import LLMGenerationData
from dify_graph.model_runtime.entities.llm_entities import LLMUsage
from dify_graph.nodes.llm.entities import LLMGenerationData
messages = [UserPromptMessage(content="Hello!")]
@ -318,7 +318,7 @@ class TestBuildContext:
class TestRestoreMultimodalContentInMessages:
"""Tests for restore_multimodal_content_in_messages function."""
@patch("core.workflow.file.file_manager.restore_multimodal_content")
@patch("dify_graph.file.file_manager.restore_multimodal_content")
def test_restores_multimodal_content(self, mock_restore):
"""Should restore multimodal content in messages."""
# Setup mock

View File

@ -3,12 +3,12 @@ from collections.abc import Generator
from typing import Any
import pytest
from core.model_runtime.entities.llm_entities import LLMUsage
from core.workflow.entities.tool_entities import ToolResultStatus
from core.workflow.nodes.llm.node import LLMNode
from dify_graph.model_runtime.entities.llm_entities import LLMUsage
from dify_graph.entities.tool_entities import ToolResultStatus
from dify_graph.nodes.llm.node import LLMNode
from core.workflow.entities import ToolCallResult
from core.workflow.node_events import ModelInvokeCompletedEvent, NodeEventBase
from dify_graph.entities import ToolCallResult
from dify_graph.node_events import ModelInvokeCompletedEvent, NodeEventBase
class _StubModelInstance:
@ -109,9 +109,9 @@ def test_stream_llm_events_no_reasoning_results_in_empty_sequence():
def test_serialize_tool_call_strips_files_to_ids():
file_cls = pytest.importorskip("core.workflow.file").File
file_type = pytest.importorskip("core.workflow.file.enums").FileType
transfer_method = pytest.importorskip("core.workflow.file.enums").FileTransferMethod
file_cls = pytest.importorskip("dify_graph.file").File
file_type = pytest.importorskip("dify_graph.file.enums").FileType
transfer_method = pytest.importorskip("dify_graph.file.enums").FileTransferMethod
file_with_id = file_cls(
id="f1",