chore(api): upgrade graphon to v0.6.0, migrate HITL logic back to Dify (#38247)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
QuantumGhost
2026-07-03 03:45:21 +00:00
committed by GitHub
co-authored by autofix-ci[bot]
parent cb6179356c
commit f4ec608ef4
89 changed files with 2345 additions and 396 deletions
@@ -8,7 +8,7 @@ from sqlalchemy import Engine, select
from sqlalchemy.orm import Session, selectinload, sessionmaker
from configs import dify_config
from graphon.nodes.human_input.enums import HumanInputFormKind, HumanInputFormStatus
from core.workflow.nodes.human_input.enums import HumanInputFormKind, HumanInputFormStatus
from libs.datetime_utils import ensure_naive_utc, naive_utc_now
from models.account import Account, Tenant
from models.enums import CreatorUserRole
+5 -5
View File
@@ -15,9 +15,7 @@ from core.repositories.human_input_repository import (
HumanInputFormSubmissionRepository,
)
from core.workflow.human_input_policy import resolve_variable_select_input_options
from factories.file_factory import build_from_mapping, build_from_mappings
from graphon.file import FileUploadConfig
from graphon.nodes.human_input.entities import (
from core.workflow.nodes.human_input.entities import (
FileInputConfig,
FileListInputConfig,
FormDefinition,
@@ -26,10 +24,12 @@ from graphon.nodes.human_input.entities import (
SelectInputConfig,
UserActionConfig,
)
from graphon.nodes.human_input.entities import (
from core.workflow.nodes.human_input.entities import (
validate_human_input_submission as graphon_validate_human_input_submission,
)
from graphon.nodes.human_input.enums import HumanInputFormKind, HumanInputFormStatus, ValueSourceType
from core.workflow.nodes.human_input.enums import HumanInputFormKind, HumanInputFormStatus, ValueSourceType
from factories.file_factory import build_from_mapping, build_from_mappings
from graphon.file import FileUploadConfig
from graphon.runtime import GraphRuntimeState
from graphon.runtime.graph_runtime_state_protocol import ReadOnlyVariablePool
from libs.datetime_utils import ensure_naive_utc, naive_utc_now
@@ -33,8 +33,11 @@ from core.workflow.human_input_policy import (
resolve_human_input_pause_reason_inputs,
resolve_variable_select_input_options,
)
from core.workflow.nodes.human_input.pause_reason import (
DifyHITLEventType,
HumanInputRequired,
)
from graphon.entities import WorkflowStartReason
from graphon.entities.pause_reason import HumanInputRequired, PauseReasonType
from graphon.enums import WorkflowExecutionStatus, WorkflowNodeExecutionStatus
from graphon.runtime import GraphRuntimeState
from graphon.runtime.graph_runtime_state_protocol import ReadOnlyVariablePool
@@ -494,7 +497,7 @@ def _build_pause_event(
human_input_form_ids = [
form_id
for reason in reasons
if reason.get("TYPE") == PauseReasonType.HUMAN_INPUT_REQUIRED
if reason.get("TYPE") == DifyHITLEventType.HUMAN_INPUT_REQUIRED
for form_id in [reason.get("form_id")]
if isinstance(form_id, str)
]
+66 -40
View File
@@ -3,6 +3,7 @@ import logging
import time
import uuid
from collections.abc import Callable, Generator, Mapping, Sequence
from dataclasses import dataclass
from typing import Any, cast
from sqlalchemy import exists, select
@@ -11,7 +12,6 @@ from sqlalchemy.orm import Session, scoped_session, sessionmaker
from configs import dify_config
from core.app.apps.advanced_chat.app_config_manager import AdvancedChatAppConfigManager
from core.app.apps.workflow.app_config_manager import WorkflowAppConfigManager
from core.app.entities.app_invoke_entities import InvokeFrom, UserFrom, build_dify_run_context
from core.app.file_access import DatabaseFileAccessController
from core.entities import PluginCredentialType
from core.plugin.impl.model_runtime_factory import create_plugin_model_assembly, create_plugin_provider_manager
@@ -25,15 +25,20 @@ from core.workflow.human_input_adapter import (
)
from core.workflow.node_factory import (
LATEST_VERSION,
DifyGraphInitContext,
get_node_type_classes_mapping,
is_start_node_type,
)
from core.workflow.node_runtime import (
DifyFileReferenceFactory,
DifyHumanInputNodeRuntime,
apply_dify_debug_email_recipient,
)
from core.workflow.nodes.human_input.callback import (
DifyHITLCallback,
render_form_content_before_submission,
resolve_default_values,
)
from core.workflow.nodes.human_input.entities import FormInputConfig, HumanInputNodeData
from core.workflow.nodes.human_input.enums import HumanInputFormKind
from core.workflow.nodes.human_input.pause_reason import HumanInputRequired
from core.workflow.system_variables import build_bootstrap_variables, build_system_variables, default_system_variables
from core.workflow.variable_pool_initializer import add_node_inputs_to_pool, add_variables_to_pool
from core.workflow.workflow_entry import WorkflowEntry
@@ -45,7 +50,6 @@ from extensions.ext_storage import storage
from factories.file_factory import build_from_mapping, build_from_mappings
from graphon.entities import WorkflowNodeExecution
from graphon.entities.graph_config import NodeConfigDict
from graphon.entities.pause_reason import HumanInputRequired
from graphon.enums import (
ErrorStrategy,
NodeType,
@@ -59,11 +63,8 @@ from graphon.node_events import NodeRunResult
from graphon.nodes import BuiltinNodeTypes
from graphon.nodes.base.node import Node
from graphon.nodes.http_request import HTTP_REQUEST_CONFIG_FILTER_KEY, build_http_request_config
from graphon.nodes.human_input.entities import HumanInputNodeData
from graphon.nodes.human_input.enums import HumanInputFormKind
from graphon.nodes.human_input.human_input_node import HumanInputNode
from graphon.nodes.start.entities import StartNodeData
from graphon.runtime import GraphRuntimeState, VariablePool
from graphon.runtime import VariablePool
from graphon.variable_loader import load_into_variable_pool
from graphon.variables import VariableBase
from graphon.variables.input_entities import VariableEntityType
@@ -82,6 +83,51 @@ from services.errors.app import (
WorkflowHashNotEqualError,
WorkflowNotFoundError,
)
@dataclass(frozen=True)
class _DebugHumanInputNode:
node_id: str
title: str
node_data: HumanInputNodeData
variable_pool: VariablePool
def render_form_content_before_submission(self) -> str:
return render_form_content_before_submission(
self.node_data,
variable_pool=self.variable_pool,
)
def resolve_default_values(self) -> Mapping[str, Any]:
return resolve_default_values(
self.node_data,
variable_pool=self.variable_pool,
)
def render_form_content_with_outputs(
self,
form_content: str,
outputs: Mapping[str, Any],
field_names: Sequence[str],
form_inputs: Sequence[FormInputConfig] | None = None,
) -> str:
return DifyHITLCallback.render_form_content_with_outputs(
form_content=form_content,
outputs=outputs, # type: ignore[arg-type]
field_names=field_names,
form_inputs=form_inputs,
)
@property
def workflow_execution_id(self) -> str:
return "debug-human-input"
@property
def node_title(self) -> str:
return self.title
HumanInputNode = _DebugHumanInputNode
from services.human_input_service import HumanInputService
from services.workflow.workflow_converter import WorkflowConverter
from services.workflow_ref_service import WorkflowRef
@@ -1276,35 +1322,15 @@ class WorkflowService:
account: Account,
node_config: NodeConfigDict,
variable_pool: VariablePool,
) -> HumanInputNode:
run_context = build_dify_run_context(
tenant_id=workflow.tenant_id,
app_id=workflow.app_id,
user_id=account.id,
user_from=UserFrom.ACCOUNT,
invoke_from=InvokeFrom.DEBUGGER,
)
graph_init_context = DifyGraphInitContext(
workflow_id=workflow.id,
graph_config=workflow.graph_dict,
run_context=run_context,
call_depth=0,
)
graph_init_params = graph_init_context.to_graph_init_params()
graph_runtime_state = GraphRuntimeState(
variable_pool=variable_pool,
start_at=time.perf_counter(),
)
node_data = HumanInputNode.validate_node_data(adapt_human_input_node_data_for_graph(node_config["data"]))
node = HumanInputNode(
) -> _DebugHumanInputNode:
_ = workflow, account
node_data = HumanInputNodeData.model_validate(adapt_human_input_node_data_for_graph(node_config["data"]))
return HumanInputNode(
node_id=node_config["id"],
data=node_data,
graph_init_params=graph_init_params,
graph_runtime_state=graph_runtime_state,
runtime=DifyHumanInputNodeRuntime(run_context),
file_reference_factory=DifyFileReferenceFactory(run_context),
title=node_data.title,
node_data=node_data,
variable_pool=variable_pool,
)
return node
def _build_human_input_variable_pool(
self,
@@ -1334,10 +1360,10 @@ class WorkflowService:
tenant_id=app_model.tenant_id,
user_id=user_id,
)
variable_mapping = HumanInputNode.extract_variable_selector_to_variable_mapping(
graph_config=workflow.graph_dict,
config=node_config,
human_input_node_data = HumanInputNodeData.model_validate(
adapt_human_input_node_data_for_graph(node_config["data"])
)
variable_mapping = human_input_node_data.extract_variable_selector_to_variable_mapping(node_config["id"])
normalized_user_inputs: dict[str, Any] = dict(manual_inputs)
load_into_variable_pool(
@@ -1586,7 +1612,7 @@ class WorkflowService:
Raises:
ValueError: If the node data format is invalid
"""
from graphon.nodes.human_input.entities import HumanInputNodeData
from core.workflow.nodes.human_input.entities import HumanInputNodeData
try:
HumanInputNodeData.model_validate(adapt_human_input_node_data_for_graph(node_data))