* test: adding some web tests (#27792) * feat: add validation to prevent saving empty opening statement in conversation opener modal (#27843) * fix(web): improve the consistency of the inputs-form UI (#27837) * fix(web): increase z-index of PortalToFollowElemContent (#27823) * fix: installation_id is missing when in tools page (#27849) * fix: avoid passing empty uniqueIdentifier to InstallFromMarketplace (#27802) Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * test: create new test scripts and update some existing test scripts o… (#27850) * feat: change feedback to forum (#27862) * chore: translate i18n files and update type definitions (#27868) Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> * Fix/template transformer line number (#27867) Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> * bump vite to 6.4.1 (#27877) * Add WEAVIATE_GRPC_ENDPOINT as designed in weaviate migration guide (#27861) Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * Fix: correct DraftWorkflowApi.post response model (#27289) Signed-off-by: Yongtao Huang <yongtaoh2022@gmail.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * fix Version 2.0.0-beta.2: Chat annotations Api Error #25506 (#27206) Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Asuka Minato <i@asukaminato.eu.org> * fix jina reader creadential migration command (#27883) * fix agent putout the output of workflow-tool twice (#26835) (#27087) * fix jina reader transform (#27922) * fix: prevent fetch version info in enterprise edition (#27923) * fix(api): fix `VariablePool.get` adding unexpected keys to variable_dictionary (#26767) Co-authored-by: -LAN- <laipz8200@outlook.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * refactor: implement tenant self queue for rag tasks (#27559) Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: -LAN- <laipz8200@outlook.com> * fix: bump brotli to 1.2.0 resloved CVE-2025-6176 (#27950) Signed-off-by: kenwoodjw <blackxin55+@gmail.com> --------- Signed-off-by: Yongtao Huang <yongtaoh2022@gmail.com> Signed-off-by: kenwoodjw <blackxin55+@gmail.com> Co-authored-by: aka James4u <smart.jamesjin@gmail.com> Co-authored-by: Novice <novice12185727@gmail.com> Co-authored-by: yangzheli <43645580+yangzheli@users.noreply.github.com> Co-authored-by: Elliott <105957288+Elliott-byte@users.noreply.github.com> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> Co-authored-by: johnny0120 <johnny0120@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Gritty_dev <101377478+codomposer@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: wangjifeng <163279492+kk-wangjifeng@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Boris Polonsky <BorisPolonsky@users.noreply.github.com> Co-authored-by: Yongtao Huang <yongtaoh2022@gmail.com> Co-authored-by: Cursx <33718736+Cursx@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Asuka Minato <i@asukaminato.eu.org> Co-authored-by: Jyong <76649700+JohnJyong@users.noreply.github.com> Co-authored-by: red_sun <56100962+redSun64@users.noreply.github.com> Co-authored-by: NFish <douxc512@gmail.com> Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com> Co-authored-by: -LAN- <laipz8200@outlook.com> Co-authored-by: hj24 <huangjian@dify.ai> Co-authored-by: kenwoodjw <blackxin55+@gmail.com> |
||
|---|---|---|
| .. | ||
| entities | ||
| graph | ||
| graph_engine | ||
| graph_events | ||
| node_events | ||
| nodes | ||
| repositories | ||
| runtime | ||
| utils | ||
| README.md | ||
| __init__.py | ||
| constants.py | ||
| conversation_variable_updater.py | ||
| enums.py | ||
| errors.py | ||
| system_variable.py | ||
| variable_loader.py | ||
| workflow_entry.py | ||
| workflow_type_encoder.py | ||
README.md
Workflow
Project Overview
This is the workflow graph engine module of Dify, implementing a queue-based distributed workflow execution system. The engine handles agentic AI workflows with support for parallel execution, node iteration, conditional logic, and external command control.
Architecture
Core Components
The graph engine follows a layered architecture with strict dependency rules:
-
Graph Engine (
graph_engine/) - Orchestrates workflow execution- Manager - External control interface for stop/pause/resume commands
- Worker - Node execution runtime
- Command Processing - Handles control commands (abort, pause, resume)
- Event Management - Event propagation and layer notifications
- Graph Traversal - Edge processing and skip propagation
- Response Coordinator - Path tracking and session management
- Layers - Pluggable middleware (debug logging, execution limits)
- Command Channels - Communication channels (InMemory, Redis)
-
Graph (
graph/) - Graph structure and runtime state- Graph Template - Workflow definition
- Edge - Node connections with conditions
- Runtime State Protocol - State management interface
-
Nodes (
nodes/) - Node implementations- Base - Abstract node classes and variable parsing
- Specific Nodes - LLM, Agent, Code, HTTP Request, Iteration, Loop, etc.
-
Events (
node_events/) - Event system- Base - Event protocols
- Node Events - Node lifecycle events
-
Entities (
entities/) - Domain models- Variable Pool - Variable storage
- Graph Init Params - Initialization configuration
Key Design Patterns
Command Channel Pattern
External workflow control via Redis or in-memory channels:
# Send stop command to running workflow
channel = RedisChannel(redis_client, f"workflow:{task_id}:commands")
channel.send_command(AbortCommand(reason="User requested"))
Layer System
Extensible middleware for cross-cutting concerns:
engine = GraphEngine(graph)
engine.layer(DebugLoggingLayer(level="INFO"))
engine.layer(ExecutionLimitsLayer(max_nodes=100))
Event-Driven Architecture
All node executions emit events for monitoring and integration:
NodeRunStartedEvent- Node execution beginsNodeRunSucceededEvent- Node completes successfullyNodeRunFailedEvent- Node encounters errorGraphRunStartedEvent/GraphRunCompletedEvent- Workflow lifecycle
Variable Pool
Centralized variable storage with namespace isolation:
# Variables scoped by node_id
pool.add(["node1", "output"], value)
result = pool.get(["node1", "output"])
Import Architecture Rules
The codebase enforces strict layering via import-linter:
-
Workflow Layers (top to bottom):
- graph_engine → graph_events → graph → nodes → node_events → entities
-
Graph Engine Internal Layers:
- orchestration → command_processing → event_management → graph_traversal → domain
-
Domain Isolation:
- Domain models cannot import from infrastructure layers
-
Command Channel Independence:
- InMemory and Redis channels must remain independent
Common Tasks
Adding a New Node Type
- Create node class in
nodes/<node_type>/ - Inherit from
BaseNodeor appropriate base class - Implement
_run()method - Register in
nodes/node_mapping.py - Add tests in
tests/unit_tests/core/workflow/nodes/
Implementing a Custom Layer
- Create class inheriting from
Layerbase - Override lifecycle methods:
on_graph_start(),on_event(),on_graph_end() - Add to engine via
engine.layer()
Debugging Workflow Execution
Enable debug logging layer:
debug_layer = DebugLoggingLayer(
level="DEBUG",
include_inputs=True,
include_outputs=True
)