[importlinter]
root_packages =
    core
    dify_graph
    configs
    controllers
    extensions
    models
    tasks
    services
include_external_packages = True

[importlinter:contract:workflow]
name = Workflow
type=layers
layers =
    graph_engine
    graph_events
    graph
    nodes
    node_events
    runtime
    entities
containers =
    dify_graph
ignore_imports =
    dify_graph.nodes.base.node -> dify_graph.graph_events
    dify_graph.nodes.iteration.iteration_node -> dify_graph.graph_events
    dify_graph.nodes.loop.loop_node -> dify_graph.graph_events

    dify_graph.nodes.iteration.iteration_node -> core.workflow.node_factory
    dify_graph.nodes.loop.loop_node -> core.workflow.node_factory
    dify_graph.nodes.iteration.iteration_node -> core.app.workflow.layers.llm_quota
    dify_graph.nodes.loop.loop_node -> core.app.workflow.layers.llm_quota

    dify_graph.nodes.iteration.iteration_node -> dify_graph.graph_engine
    dify_graph.nodes.iteration.iteration_node -> dify_graph.graph
    dify_graph.nodes.iteration.iteration_node -> dify_graph.graph_engine.command_channels
    dify_graph.nodes.loop.loop_node -> dify_graph.graph_engine
    dify_graph.nodes.loop.loop_node -> dify_graph.graph
    dify_graph.nodes.loop.loop_node -> dify_graph.graph_engine.command_channels
    # TODO(QuantumGhost): fix the import violation later
    dify_graph.entities.pause_reason -> dify_graph.nodes.human_input.entities

[importlinter:contract:workflow-infrastructure-dependencies]
name = Workflow Infrastructure Dependencies
type = forbidden
source_modules =
    dify_graph
forbidden_modules =
    extensions.ext_database
    extensions.ext_redis
allow_indirect_imports = True
ignore_imports =
    dify_graph.nodes.agent.agent_node -> extensions.ext_database
    dify_graph.nodes.llm.file_saver -> extensions.ext_database
    dify_graph.nodes.llm.node -> extensions.ext_database
    dify_graph.nodes.tool.tool_node -> extensions.ext_database
    dify_graph.model_runtime.model_providers.__base.ai_model -> extensions.ext_redis
    dify_graph.model_runtime.model_providers.model_provider_factory -> extensions.ext_redis
    # TODO(QuantumGhost): use DI to avoid depending on global DB.
    dify_graph.nodes.human_input.human_input_node -> extensions.ext_database

[importlinter:contract:workflow-external-imports]
name = Workflow External Imports
type = forbidden
source_modules =
    dify_graph
forbidden_modules =
    configs
    controllers
    extensions
    models
    services
    tasks
    core.agent
    core.app
    core.base
    core.callback_handler
    core.datasource
    core.db
    core.entities
    core.errors
    core.extension
    core.external_data_tool
    core.file
    core.helper
    core.hosting_configuration
    core.indexing_runner
    core.llm_generator
    core.logging
    core.mcp
    core.memory
    core.moderation
    core.ops
    core.plugin
    core.prompt
    core.provider_manager
    core.rag
    core.repositories
    core.schemas
    core.tools
    core.trigger
    core.variables
ignore_imports =
    dify_graph.nodes.loop.loop_node -> core.workflow.node_factory
    dify_graph.nodes.agent.agent_node -> core.model_manager
    dify_graph.nodes.agent.agent_node -> core.provider_manager
    dify_graph.nodes.agent.agent_node -> core.tools.tool_manager
    dify_graph.nodes.document_extractor.node -> core.helper.ssrf_proxy
    dify_graph.nodes.iteration.iteration_node -> core.workflow.node_factory
    dify_graph.nodes.iteration.iteration_node -> core.app.workflow.layers.llm_quota
    dify_graph.nodes.llm.llm_utils -> core.model_manager
    dify_graph.nodes.llm.protocols -> core.model_manager
    dify_graph.nodes.llm.llm_utils -> dify_graph.model_runtime.model_providers.__base.large_language_model
    dify_graph.nodes.llm.node -> core.tools.signature
    dify_graph.nodes.tool.tool_node -> core.callback_handler.workflow_tool_callback_handler
    dify_graph.nodes.tool.tool_node -> core.tools.tool_engine
    dify_graph.nodes.tool.tool_node -> core.tools.tool_manager
    dify_graph.nodes.agent.agent_node -> core.agent.entities
    dify_graph.nodes.agent.agent_node -> core.agent.plugin_entities
    dify_graph.nodes.knowledge_retrieval.knowledge_retrieval_node -> core.app.app_config.entities
    dify_graph.nodes.parameter_extractor.parameter_extractor_node -> core.prompt.advanced_prompt_transform
    dify_graph.nodes.parameter_extractor.parameter_extractor_node -> core.prompt.simple_prompt_transform
    dify_graph.nodes.parameter_extractor.parameter_extractor_node -> dify_graph.model_runtime.model_providers.__base.large_language_model
    dify_graph.nodes.question_classifier.question_classifier_node -> core.prompt.simple_prompt_transform
    dify_graph.nodes.parameter_extractor.parameter_extractor_node -> core.model_manager
    dify_graph.nodes.question_classifier.question_classifier_node -> core.model_manager
    dify_graph.nodes.tool.tool_node -> core.tools.utils.message_transformer
    dify_graph.nodes.tool.tool_node -> models
    dify_graph.nodes.agent.agent_node -> models.model
    dify_graph.nodes.llm.file_saver -> core.helper.ssrf_proxy
    dify_graph.nodes.llm.node -> core.helper.code_executor
    dify_graph.nodes.llm.node -> core.llm_generator.output_parser.errors
    dify_graph.nodes.llm.node -> core.llm_generator.output_parser.structured_output
    dify_graph.nodes.llm.node -> core.model_manager
    dify_graph.nodes.agent.entities -> core.prompt.entities.advanced_prompt_entities
    dify_graph.nodes.llm.entities -> core.prompt.entities.advanced_prompt_entities
    dify_graph.nodes.llm.node -> core.prompt.entities.advanced_prompt_entities
    dify_graph.nodes.llm.node -> core.prompt.utils.prompt_message_util
    dify_graph.nodes.parameter_extractor.entities -> core.prompt.entities.advanced_prompt_entities
    dify_graph.nodes.parameter_extractor.parameter_extractor_node -> core.prompt.entities.advanced_prompt_entities
    dify_graph.nodes.parameter_extractor.parameter_extractor_node -> core.prompt.utils.prompt_message_util
    dify_graph.nodes.question_classifier.entities -> core.prompt.entities.advanced_prompt_entities
    dify_graph.nodes.question_classifier.question_classifier_node -> core.prompt.utils.prompt_message_util
    dify_graph.nodes.knowledge_index.entities -> core.rag.retrieval.retrieval_methods
    dify_graph.nodes.llm.node -> models.dataset
    dify_graph.nodes.agent.agent_node -> core.tools.utils.message_transformer
    dify_graph.nodes.llm.file_saver -> core.tools.signature
    dify_graph.nodes.llm.file_saver -> core.tools.tool_file_manager
    dify_graph.nodes.tool.tool_node -> core.tools.errors
    dify_graph.nodes.agent.agent_node -> extensions.ext_database
    dify_graph.nodes.llm.file_saver -> extensions.ext_database
    dify_graph.nodes.llm.node -> extensions.ext_database
    dify_graph.nodes.tool.tool_node -> extensions.ext_database
    dify_graph.nodes.human_input.human_input_node -> extensions.ext_database
    dify_graph.nodes.human_input.human_input_node -> core.repositories.human_input_repository
    dify_graph.nodes.agent.agent_node -> models
    dify_graph.nodes.loop.loop_node -> core.app.workflow.layers.llm_quota
    dify_graph.nodes.llm.node -> models.model
    dify_graph.nodes.agent.agent_node -> services
    dify_graph.nodes.tool.tool_node -> services
    dify_graph.model_runtime.model_providers.__base.ai_model -> configs
    dify_graph.model_runtime.model_providers.__base.ai_model -> extensions.ext_redis
    dify_graph.model_runtime.model_providers.__base.large_language_model -> configs
    dify_graph.model_runtime.model_providers.__base.text_embedding_model -> core.entities.embedding_type
    dify_graph.model_runtime.model_providers.model_provider_factory -> configs
    dify_graph.model_runtime.model_providers.model_provider_factory -> extensions.ext_redis
    dify_graph.model_runtime.model_providers.model_provider_factory -> models.provider_ids

[importlinter:contract:rsc]
name = RSC
type = layers
layers =
    graph_engine
    response_coordinator
containers =
    dify_graph.graph_engine

[importlinter:contract:worker]
name = Worker
type = layers
layers =
    graph_engine
    worker
containers =
    dify_graph.graph_engine

[importlinter:contract:graph-engine-architecture]
name = Graph Engine Architecture
type = layers
layers =
    graph_engine
    orchestration
    command_processing
    event_management
    error_handler
    graph_traversal
    graph_state_manager
    worker_management
    domain
containers =
    dify_graph.graph_engine

[importlinter:contract:domain-isolation]
name = Domain Model Isolation
type = forbidden
source_modules =
    dify_graph.graph_engine.domain
forbidden_modules =
    dify_graph.graph_engine.worker_management
    dify_graph.graph_engine.command_channels
    dify_graph.graph_engine.layers
    dify_graph.graph_engine.protocols

[importlinter:contract:worker-management]
name = Worker Management
type = forbidden
source_modules =
    dify_graph.graph_engine.worker_management
forbidden_modules =
    dify_graph.graph_engine.orchestration
    dify_graph.graph_engine.command_processing
    dify_graph.graph_engine.event_management


[importlinter:contract:graph-traversal-components]
name = Graph Traversal Components
type = layers
layers =
    edge_processor
    skip_propagator
containers =
    dify_graph.graph_engine.graph_traversal

[importlinter:contract:command-channels]
name = Command Channels Independence
type = independence
modules =
    dify_graph.graph_engine.command_channels.in_memory_channel
    dify_graph.graph_engine.command_channels.redis_channel
