diff --git a/api/core/workflow/nodes/agent/entities.py b/api/core/workflow/nodes/agent/entities.py index 51452c29a3f..16e026939df 100644 --- a/api/core/workflow/nodes/agent/entities.py +++ b/api/core/workflow/nodes/agent/entities.py @@ -1,7 +1,7 @@ from enum import IntEnum, StrEnum, auto from typing import Any, Literal, Union -from pydantic import BaseModel +from pydantic import BaseModel, Field from core.prompt.entities.advanced_prompt_entities import MemoryConfig from core.tools.entities.tool_entities import ToolSelector @@ -11,9 +11,9 @@ from graphon.enums import BuiltinNodeTypes, NodeType class AgentNodeData(BaseNodeData): type: NodeType = BuiltinNodeTypes.AGENT - agent_strategy_provider_name: str - agent_strategy_name: str - agent_strategy_label: str + agent_strategy_provider_name: str = "" + agent_strategy_name: str = "" + agent_strategy_label: str = "" memory: MemoryConfig | None = None # The version of the tool parameter. # If this value is None, it indicates this is a previous version @@ -24,7 +24,7 @@ class AgentNodeData(BaseNodeData): value: Union[list[str], list[ToolSelector], Any] type: Literal["mixed", "variable", "constant"] - agent_parameters: dict[str, AgentInput] + agent_parameters: dict[str, AgentInput] = Field(default_factory=dict) class ParamsAutoGenerated(IntEnum): diff --git a/api/tests/unit_tests/core/workflow/nodes/agent/test_agent_entities.py b/api/tests/unit_tests/core/workflow/nodes/agent/test_agent_entities.py new file mode 100644 index 00000000000..023fccbefd3 --- /dev/null +++ b/api/tests/unit_tests/core/workflow/nodes/agent/test_agent_entities.py @@ -0,0 +1,58 @@ +from core.app.entities.app_invoke_entities import InvokeFrom, UserFrom, build_dify_run_context +from core.workflow.node_factory import DifyNodeFactory +from core.workflow.nodes.agent.entities import AgentNodeData +from graphon.entities import GraphInitParams +from graphon.graph import Graph +from graphon.graph_engine import GraphEngine, GraphEngineConfig +from graphon.graph_engine.command_channels import InMemoryChannel +from graphon.graph_events import GraphNodeEventBase, GraphRunSucceededEvent +from graphon.runtime import GraphRuntimeState, VariablePool + + +def test_agent_node_data_unconfigured_defaults() -> None: + data = AgentNodeData.model_validate({"title": "Agent"}) + + assert data.agent_strategy_provider_name == "" + assert data.agent_strategy_name == "" + assert data.agent_strategy_label == "" + assert not data.agent_parameters + + +def test_unconfigured_disconnected_agent_does_not_block_workflow() -> None: + graph_config: dict[str, object] = { + "nodes": [ + {"id": "start", "data": {"type": "start", "title": "Start", "variables": []}}, + {"id": "agent", "data": {"type": "agent", "title": "Agent", "tool_node_version": "2"}}, + ], + "edges": [], + } + graph_runtime_state = GraphRuntimeState(variable_pool=VariablePool(), start_at=0) + graph_init_params = GraphInitParams( + workflow_id="workflow", + graph_config=graph_config, + run_context=build_dify_run_context( + tenant_id="tenant", + app_id="app", + user_id="user", + user_from=UserFrom.ACCOUNT, + invoke_from=InvokeFrom.DEBUGGER, + ), + call_depth=0, + ) + graph = Graph.init( + graph_config=graph_config, + node_factory=DifyNodeFactory(graph_init_params, graph_runtime_state), + root_node_id="start", + ) + engine = GraphEngine( + workflow_id="workflow", + graph=graph, + graph_runtime_state=graph_runtime_state, + command_channel=InMemoryChannel(), + config=GraphEngineConfig(min_workers=1, max_workers=1), + ) + + events = list(engine.run()) + + assert isinstance(events[-1], GraphRunSucceededEvent) + assert not any(isinstance(event, GraphNodeEventBase) and event.node_id == "agent" for event in events)