Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
e2d48b4
test(api): migrate graph and node coverage to injected runtime adapters
41tair Oct 8, 2026
567f97f
Merge updated stack base and resolve conflicts in refactor/api-76-2
41tair Oct 8, 2026
f96e815
Merge updated stack base into refactor/api-76-3
41tair Oct 8, 2026
278cfa2
Merge updated stack base into refactor/api-76-4
41tair Oct 8, 2026
bb4ae40
Merge updated stack base and resolve conflicts in refactor/api-76-5
41tair Oct 8, 2026
cfd5af6
Merge updated stack base into refactor/api-76-6
41tair Oct 8, 2026
d22e665
Merge updated stack base into refactor/api-76-7
41tair Oct 8, 2026
cbdc06b
Merge updated stack base into refactor/api-76-8
41tair Oct 8, 2026
c53e4d5
Merge updated stack base into refactor/api-76-9
41tair Oct 8, 2026
58fa758
Merge updated stack base into refactor/api-76-10-1
41tair Oct 8, 2026
8a76ef2
Merge updated stack base and resolve conflicts in refactor/api-76-10-2
41tair Oct 8, 2026
dbca91b
Merge updated stack base into refactor/api-76-10-3
41tair Oct 8, 2026
52279ff
Merge updated stack base into refactor/api-76-10-4
41tair Oct 8, 2026
840def6
Merge updated stack base and resolve conflicts in refactor/api-76-10-5
41tair Oct 8, 2026
35ebf9a
Merge updated stack base and resolve conflicts in refactor/api-76-10-6
41tair Oct 8, 2026
1b784b7
Merge updated stack base into refactor/api-76-10-6
41tair Oct 8, 2026
6585170
test(workflow): align graph fixtures and tool invocation with injecte…
41tair Oct 9, 2026
0f27c7f
Merge updated stack base into refactor/api-76-10-6
41tair Oct 9, 2026
0ef5170
Merge updated refactor/api-76-10-5
41tair Oct 15, 2026
7f3c7d4
Merge updated refactor/api-76-10-5 into refactor/api-76-10-6
41tair Oct 19, 2026
6ce28aa
Merge updated refactor/api-76-10-5 into refactor/api-76-10-6
41tair Oct 19, 2026
fed242f
Merge updated refactor/api-76-10-5 into refactor/api-76-10-6
41tair Oct 19, 2026
aae2a74
Merge updated refactor/api-76-10-5 into refactor/api-76-10-6
41tair Oct 19, 2026
e9b2882
Merge updated refactor/api-76-10-6 parent with Graphon 0.8 compatibility
41tair Oct 20, 2026
2b38909
Merge workflow migration compatibility from updated parent
41tair Oct 20, 2026
f920768
Merge execution test compatibility from updated parent
41tair Oct 20, 2026
0b777f7
test(api): adapt tests to merged execution interfaces
41tair Oct 20, 2026
bbd1d00
Merge updated refactor/api-76-10-5 into refactor/api-76-10-6
41tair Oct 26, 2026
481a50f
Sync validated refactor/api-76-10-5 fixes
41tair Oct 26, 2026
3244217
Align workflow node tests with injected dependencies and canonical ow…
41tair Oct 26, 2026
a1194f5
Sync validated refactor/api-76-10-5 fixes
41tair Oct 26, 2026
a7430d5
Sync validated refactor/api-76-10-5 fixes
41tair Oct 26, 2026
d3909a5
Sync validated refactor/api-76-10-5 fixes
41tair Oct 26, 2026
0f03ee3
Sync validated refactor/api-76-10-5 fixes
41tair Oct 26, 2026
a9e39a3
Sync validated refactor/api-76-10-5 fixes
41tair Oct 26, 2026
dd9aaba
Sync validated refactor/api-76-10-5 fixes
41tair Oct 26, 2026
0a85750
Sync validated refactor/api-76-10-5 fixes
41tair Oct 27, 2026
1b3a76b
Sync validated refactor/api-76-10-5 fixes
41tair Oct 27, 2026
806aed0
Sync validated refactor/api-76-10-5 fixes
41tair Oct 27, 2026
145baa5
[autofix.ci] apply automated fixes
autofix-ci[bot] Oct 27, 2026
819381e
Merge updated refactor/api-76-10-5 into refactor/api-76-10-6
41tair Oct 31, 2026
f022d7f
Sync validated refactor/api-76-10-5 fixes
41tair Oct 31, 2026
6d76136
Sync validated refactor/api-76-10-5 fixes
41tair Oct 31, 2026
099acb5
Sync validated refactor/api-76-10-5 fixes
41tair Oct 31, 2026
266e6a4
Sync validated refactor/api-76-10-5 fixes
41tair Oct 31, 2026
6174b36
Sync validated refactor/api-76-10-5 fixes
41tair Oct 31, 2026
a158bf4
Sync validated refactor/api-76-10-5 fixes
41tair Oct 31, 2026
7be9003
Sync validated refactor/api-76-10-5 fixes
41tair Oct 31, 2026
2e06c46
Sync validated refactor/api-76-10-4 fixes
41tair Oct 31, 2026
bd02eaf
Sync validated refactor/api-76-10-5 fixes
41tair Oct 31, 2026
fef4f7b
Sync validated refactor/api-76-10-5 fixes
41tair Oct 31, 2026
54edb6a
Sync validated refactor/api-76-10-5 fixes
41tair Oct 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,8 @@
from collections.abc import Mapping
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Any, Protocol
from typing import Any, Protocol, cast

from core.repositories.human_input_repository import (
FormCreateParams,
HumanInputFormEntity,
HumanInputFormRepository,
)
from core.workflow.node_runtime import DifyHumanInputNodeRuntime
from core.workflow.nodes.human_input.callback import (
DifyHITLCallback,
)
from core.workflow.system_variables import build_system_variables
from enums.human_input import HumanInputFormStatus, ValueSourceType
from graphon.engine import Engine
Expand All @@ -29,11 +20,18 @@
from graphon.nodes.base.entities import OutputVariableEntity
from graphon.nodes.end.end_node import EndNode
from graphon.nodes.end.entities import EndNodeData
from graphon.nodes.human_input.entities import HumanInputNodeData as GraphonHumanInputNodeData
from graphon.nodes.human_input.human_input_node import HumanInputNode
from graphon.nodes.start.entities import StartNodeData
from graphon.nodes.start.start_node import StartNode
from graphon.runtime import RuntimeState, VariablePool
from libs.datetime_utils import naive_utc_now
from models.human_input_contracts import (
FormCreateParams,
HumanInputFormEntity,
HumanInputFormRecipientEntity,
HumanInputFormRepository,
)
from models.human_input_entities import (
FileInputConfig,
FileListInputConfig,
Expand All @@ -42,6 +40,10 @@
StringListSource,
UserActionConfig,
)
from services.workflow.execution.adapters.human_input import (
DifyHITLCallback,
)
from services.workflow.execution.adapters.node_runtime import DifyFileReferenceFactory
from tests.workflow_test_utils import build_test_graph_init_params


Expand Down Expand Up @@ -94,11 +96,7 @@ def id(self) -> str:
return self.form_id

@property
def submission_token(self) -> str | None:
return "token"

@property
def recipients(self) -> list:
def recipients(self) -> list[HumanInputFormRecipientEntity]:
return []

@property
Expand Down Expand Up @@ -134,7 +132,8 @@ class StaticRepo(HumanInputFormRepository):
def __init__(self, forms_by_node_id: Mapping[str, HumanInputFormEntity]) -> None:
self._forms_by_node_id = dict(forms_by_node_id)

def get_form(self, node_id: str) -> HumanInputFormEntity | None:
def get_form(self, node_id: str, *, form_id: str | None = None) -> HumanInputFormEntity | None:
_ = form_id
return self._forms_by_node_id.get(node_id)

def set_forms(self, forms_by_node_id: Mapping[str, HumanInputFormEntity]) -> None:
Expand Down Expand Up @@ -197,32 +196,28 @@ def _build_graph(runtime_state: RuntimeState, repo: HumanInputFormRepository) ->
)

human_a_config = {"id": "human_a", "data": human_data.model_dump()}
human_a_runtime = DifyHumanInputNodeRuntime(graph_init_params.run_context)
human_a_runtime._file_reference_factory = _TestFileReferenceFactory() # type: ignore[attr-defined]
human_a_callback = DifyHITLCallback(
form_repository=repo,
node_data=human_data,
file_reference_factory=_TestFileReferenceFactory(),
file_reference_factory=cast(DifyFileReferenceFactory, _TestFileReferenceFactory()),
)
human_a = HumanInputNode(
node_id=human_a_config["id"],
data=human_data,
data=GraphonHumanInputNodeData.model_validate(human_data.model_dump()),
init_params=graph_init_params,
runtime_state=runtime_state,
hitl_callback=human_a_callback,
)

human_b_config = {"id": "human_b", "data": human_data.model_dump()}
human_b_runtime = DifyHumanInputNodeRuntime(graph_init_params.run_context)
human_b_runtime._file_reference_factory = _TestFileReferenceFactory() # type: ignore[attr-defined]
human_b_callback = DifyHITLCallback(
form_repository=repo,
node_data=human_data,
file_reference_factory=_TestFileReferenceFactory(),
file_reference_factory=cast(DifyFileReferenceFactory, _TestFileReferenceFactory()),
)
human_b = HumanInputNode(
node_id=human_b_config["id"],
data=human_data,
data=GraphonHumanInputNodeData.model_validate(human_data.model_dump()),
init_params=graph_init_params,
runtime_state=runtime_state,
hitl_callback=human_b_callback,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
from core.workflow.workflow_entry import iter_dify_graph_engine_events
from graphon.engine import Engine
from graphon.engine.command import InMemoryChannel
from graphon.engine_events import (
GraphRunSucceededEvent,
NodeRunStreamChunkEvent,
)
from services.workflow.execution.adapters.workflow_entry import iter_dify_graph_engine_events
from tests.helpers.workflow.mock_config import MockConfigBuilder
from tests.helpers.workflow.table_runner import TableTestRunner
from tests.unit_tests.workflow_execution import NO_HUMAN_INPUT_FORMS


def test_tool_in_chatflow():
def test_tool_in_chatflow() -> None:
runner = TableTestRunner()

# Load the workflow configuration
Expand All @@ -29,7 +30,7 @@ def test_tool_in_chatflow():
command_channel=InMemoryChannel(),
)

events = list(iter_dify_graph_engine_events(engine))
events = list(iter_dify_graph_engine_events(engine, human_form_reader=NO_HUMAN_INPUT_FORMS))

# Check for successful completion
success_events = [e for e in events if isinstance(e, GraphRunSucceededEvent)]
Expand All @@ -42,7 +43,7 @@ def test_tool_in_chatflow():
assert success_events[-1].outputs["answer"] == "hello, dify!"


def test_answer_can_render_llm_structured_output_in_chatflow():
def test_answer_can_render_llm_structured_output_in_chatflow() -> None:
runner = TableTestRunner()

fixture_data = runner.workflow_runner.load_fixture("basic_chatflow")
Expand Down Expand Up @@ -81,7 +82,7 @@ def test_answer_can_render_llm_structured_output_in_chatflow():
command_channel=InMemoryChannel(),
)

events = list(iter_dify_graph_engine_events(engine))
events = list(iter_dify_graph_engine_events(engine, human_form_reader=NO_HUMAN_INPUT_FORMS))
success_events = [e for e in events if isinstance(e, GraphRunSucceededEvent)]

assert success_events, "Workflow should complete successfully"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import pytest

from core.workflow.node_factory import get_node_type_classes_mapping
from graphon.entities.base_node_data import BaseNodeData
from graphon.enums import BuiltinNodeTypes, NodeType
from graphon.nodes.base.node import Node
from services.workflow.execution.adapters.node_factory import get_node_type_classes_mapping

# Ensures that all production node classes are imported and registered.
_ = get_node_type_classes_mapping()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
from core.app.entities.app_invoke_entities import InvokeFrom, UserFrom
from core.helper.ssrf_proxy import ssrf_proxy
from core.tools.tool_file_manager import ToolFileManager
from core.workflow.node_runtime import DifyFileReferenceFactory
from core.workflow.system_variables import build_system_variables
from graphon.enums import WorkflowNodeExecutionStatus
from graphon.file.file_manager import file_manager
from graphon.nodes.http_request import HTTP_REQUEST_CONFIG_FILTER_KEY, HttpRequestNode, HttpRequestNodeConfig
from graphon.nodes.http_request.entities import HttpRequestNodeData, HttpRequestNodeTimeout, Response
from graphon.runtime import RuntimeState, VariablePool
from services.workflow.execution.adapters.node_runtime import DifyFileReferenceFactory
from tests.workflow_test_utils import build_test_graph_init_params

HTTP_REQUEST_CONFIG = HttpRequestNodeConfig(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from core.model_manager import ModelInstance
from core.plugin.impl.model_runtime_factory import create_plugin_model_assembly
from core.prompt.entities.advanced_prompt_entities import MemoryConfig
from core.workflow.node_runtime import DifyFileReferenceFactory, DifyPromptMessageSerializer, DifyToolFileManager
from core.workflow.system_variables import default_system_variables
from graphon.file import File, FileTransferMethod, FileType
from graphon.model_runtime.entities.common_entities import I18nObject
Expand Down Expand Up @@ -88,6 +87,11 @@
from graphon.template_rendering import TemplateRenderError
from graphon.variables import ArrayAnySegment, ArrayFileSegment, NoneSegment
from models.provider import ProviderType
from services.workflow.execution.adapters.node_runtime import (
DifyFileReferenceFactory,
DifyPromptMessageSerializer,
DifyToolFileManager,
)
from tests.workflow_test_utils import build_test_graph_init_params


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
from typing import cast

from core.app.entities.app_invoke_entities import InvokeFrom, UserFrom
from core.workflow.node_factory import DifyNodeFactory
from core.workflow.system_variables import build_system_variables
from graphon.enums import WorkflowNodeExecutionStatus
from graphon.graph import Graph
from graphon.nodes.template_transform.entities import TemplateTransformNodeData
from graphon.nodes.template_transform.template_transform_node import TemplateTransformNode
from graphon.runtime import RuntimeState, VariablePool
from graphon.template_rendering import Jinja2TemplateRenderer, TemplateRenderError
from services.workflow.execution.adapters.node_factory import DifyNodeFactory
from tests.workflow_test_utils import build_test_graph_init_params


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
import pytest

from core.app.entities.app_invoke_entities import InvokeFrom, UserFrom
from core.workflow.node_runtime import resolve_dify_run_context
from core.workflow.system_variables import build_system_variables
from graphon.entities.base_node_data import BaseNodeData
from graphon.enums import BuiltinNodeTypes
from graphon.nodes.base.node import Node
from graphon.runtime import InitParams, RuntimeState, VariablePool
from services.workflow.execution.adapters.node_runtime import resolve_dify_run_context
from tests.workflow_test_utils import build_test_graph_init_params


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import pytest

from core.app.entities.app_invoke_entities import DIFY_RUN_CONTEXT_KEY, InvokeFrom, UserFrom
from core.workflow.node_factory import DifyNodeFactory
from core.workflow.system_variables import build_system_variables
from graphon.enums import WorkflowNodeExecutionStatus
from graphon.file import File, FileTransferMethod, FileType
Expand All @@ -15,6 +14,7 @@
from graphon.runtime import RuntimeState, VariablePool
from graphon.utils.condition.entities import Condition, SubCondition, SubVariableCondition
from graphon.variables import ArrayFileSegment
from services.workflow.execution.adapters.node_factory import DifyNodeFactory
from tests.workflow_test_utils import build_test_graph_init_params


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from pytest_mock import MockerFixture

from core.tools.tool_file_manager import ToolFileManager
from core.workflow.node_runtime import DifyToolFileManager
from core.workflow.system_variables import build_system_variables
from graphon.file import File, FileTransferMethod, FileType
from graphon.model_runtime.entities.llm_entities import LLMUsage
Expand All @@ -20,6 +19,7 @@
from graphon.nodes.tool_runtime_entities import ToolRuntimeHandle, ToolRuntimeMessage
from graphon.runtime import RuntimeState
from graphon.variables.segments import ArrayFileSegment
from services.workflow.execution.adapters.node_runtime import DifyToolFileManager
from tests.workflow_test_utils import build_test_graph_init_params, build_test_variable_pool

if TYPE_CHECKING: # pragma: no cover - imported for type checking only
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,31 +102,34 @@ def test_moved_core_nodes_resolve_after_importing_production_entrypoints() -> No
script = textwrap.dedent(
"""
from core.app.apps import workflow_app_runner
from core.workflow import workflow_entry
from core.workflow.nodes.datasource.datasource_node import DatasourceNode
from core.workflow.nodes.knowledge_index import KNOWLEDGE_INDEX_NODE_TYPE
from core.workflow.node_factory import (
from core.workflow.nodes.knowledge_index.knowledge_index_node import KnowledgeIndexNode
from services.workflow.execution.adapters import workflow_entry
from services.workflow.execution.adapters.knowledge_retrieval import KnowledgeRetrievalNode
from services.workflow.execution.adapters.node_factory import (
DifyNodeFactory,
NODE_TYPE_CLASSES_MAPPING,
resolve_workflow_node_class,
)
from core.workflow.nodes.agent import AgentNode
from core.workflow.nodes.agent_v2 import DifyAgentNode
from graphon.enums import BuiltinNodeTypes
from services import workflow_service
from services.rag_pipeline import rag_pipeline
from services.workflow.execution.adapters.agent_node import AgentNode
from services.workflow.execution.adapters.agent_v2.agent_node import DifyAgentNode

_ = workflow_entry, workflow_app_runner, workflow_service, rag_pipeline

expected = (
BuiltinNodeTypes.KNOWLEDGE_RETRIEVAL,
KNOWLEDGE_INDEX_NODE_TYPE,
BuiltinNodeTypes.DATASOURCE,
)
expected = {
BuiltinNodeTypes.KNOWLEDGE_RETRIEVAL: KnowledgeRetrievalNode,
KNOWLEDGE_INDEX_NODE_TYPE: KnowledgeIndexNode,
BuiltinNodeTypes.DATASOURCE: DatasourceNode,
}

for node_type in expected:
for node_type, node_class in expected.items():
assert node_type in NODE_TYPE_CLASSES_MAPPING, node_type
resolved = DifyNodeFactory._resolve_node_class(node_type=node_type, node_version="1")
assert resolved.__module__.startswith("core.workflow.nodes."), resolved.__module__
assert resolved is node_class, (node_type, resolved)

assert DifyNodeFactory._resolve_node_class(
node_type=BuiltinNodeTypes.AGENT,
Expand Down
2 changes: 1 addition & 1 deletion api/tests/helpers/workflow/mock_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
from typing import TYPE_CHECKING, Any, override

from core.workflow.human_input_adapter import adapt_node_config_for_graph
from core.workflow.node_factory import DifyNodeFactory
from graphon.entities.base_node_data import BaseNodeData
from graphon.entities.graph_config import NodeConfigDict, NodeConfigDictAdapter
from graphon.enums import BuiltinNodeTypes, NodeType
from graphon.nodes.base.node import Node
from services.workflow.execution.adapters.node_factory import DifyNodeFactory
from tests.helpers.workflow.mock_nodes import (
MockAgentNode,
MockCodeNode,
Expand Down
22 changes: 11 additions & 11 deletions api/tests/helpers/workflow/mock_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,6 @@

from core.app.llm.model_access import DifyCredentialsProvider, DifyModelFactory
from core.helper.ssrf_proxy import graphon_ssrf_proxy
from core.workflow.node_runtime import (
DifyFileReferenceFactory,
DifyPreparedLLM,
DifyPromptMessageSerializer,
DifyToolFileManager,
DifyToolNodeRuntime,
build_dify_llm_file_saver,
resolve_dify_run_context,
)
from core.workflow.nodes.agent import AgentNode
from core.workflow.nodes.knowledge_retrieval.knowledge_retrieval_node import KnowledgeRetrievalNode
from graphon.enums import WorkflowNodeExecutionMetadataKey, WorkflowNodeExecutionStatus
from graphon.model_runtime.entities.llm_entities import LLMUsage
from graphon.node_events import NodeRunResult, StreamChunkEvent, StreamCompletedEvent
Expand All @@ -37,6 +26,17 @@
from graphon.nodes.template_transform import TemplateTransformNode
from graphon.nodes.tool import ToolNode
from graphon.template_rendering import Jinja2TemplateRenderer, TemplateRenderError
from services.workflow.execution.adapters.agent_node import AgentNode
from services.workflow.execution.adapters.knowledge_retrieval import KnowledgeRetrievalNode
from services.workflow.execution.adapters.node_runtime import (
DifyFileReferenceFactory,
DifyPreparedLLM,
DifyPromptMessageSerializer,
DifyToolFileManager,
DifyToolNodeRuntime,
build_dify_llm_file_saver,
resolve_dify_run_context,
)
from tests.helpers.unit.core.model_fixtures import make_model_instance

if TYPE_CHECKING:
Expand Down
Loading
Loading