Merge branch 'main' into feat/dify-builder

This commit is contained in:
twwu committed 2026-10-26 17:50:58 +08:00
commit 35c5afb0c5
4715 files changed
+573354 -179240

No files matched your search

+51
View File
@@ -5,6 +5,7 @@ from dataclasses import dataclass
from enum import Enum
from typing import TYPE_CHECKING, Any, Literal, Protocol, cast, overload, override, runtime_checkable
from flask import current_app
from pydantic import JsonValue
from sqlalchemy import select
from sqlalchemy.orm import Session, sessionmaker
@@ -75,6 +76,7 @@ from graphon.nodes.tool_runtime_entities import (
ToolRuntimeMessage,
ToolRuntimeParameter,
)
from graphon.workflow_type_encoder import WorkflowRuntimeTypeConverter
from models.dataset import SegmentAttachmentBinding
from models.model import UploadFile
from runtime_contracts.builder.execution import (
@@ -92,6 +94,7 @@ from .human_input_adapter import (
parse_human_input_delivery_methods,
)
from .system_variables import SystemVariableKey, get_system_text
from .workflow_tool_container_types import WorkflowToolContainerPayload
class PollingLLMRuntimeProtocol(Protocol):
@@ -123,6 +126,7 @@ class PollingLLMRuntimeProtocol(Protocol):
if TYPE_CHECKING:
from core.tools.__base.tool import Tool
from core.tools.entities.tool_entities import ToolInvokeMessage as CoreToolInvokeMessage
from core.tools.workflow_as_tool.tool import WorkflowTool
from graphon.nodes.llm.file_saver import LLMFileSaver
from graphon.nodes.tool.entities import ToolNodeData
from runtime_contracts.workflow_driver import WorkflowRunDriver
@@ -544,6 +548,7 @@ class DifyToolNodeRuntime(ToolNodeRuntimeProtocol):
confirmed_guard: ConfirmedToolGuard | None = None,
confirmed_guard_factory: Callable[[str, str], ConfirmedToolGuard] | None = None,
execution_driver: WorkflowRunDriver | None = None,
workflow_tools: Mapping[str, WorkflowTool] | None = None,
) -> None:
"""Both confirmed arguments are ``None`` for every ordinary run; at most one may be set.
@@ -566,6 +571,7 @@ class DifyToolNodeRuntime(ToolNodeRuntimeProtocol):
self._workflow_id = workflow_id
self._session_maker = session_maker
self._execution_driver = execution_driver
self._workflow_tools = workflow_tools if workflow_tools is not None else {}
self._confirmed_guard = confirmed_guard
self._confirmed_guard_factory = confirmed_guard_factory
self._confirmed_guard_factory_called = False
@@ -625,6 +631,11 @@ class DifyToolNodeRuntime(ToolNodeRuntimeProtocol):
self._run_context.invoke_from,
variable_pool,
execution_driver=self._execution_driver,
workflow_tool_definition=(
self._workflow_tools.get(node_data.provider_id)
if self._is_workflow_tool_provider(node_data)
else None
),
**draft_options,
)
else:
@@ -641,6 +652,7 @@ class DifyToolNodeRuntime(ToolNodeRuntimeProtocol):
variable_pool,
confirmed_guard=guard,
)
tool_runtime.runtime.dify_run_context = self._run_context
except BuilderExecutionPolicyError as exc:
# Declared refusals carry only their fixed reason code.
raise ToolRuntimeResolutionError(str(exc)) from exc
@@ -900,6 +912,39 @@ class DifyToolNodeRuntime(ToolNodeRuntimeProtocol):
return LLMUsage.model_validate(latest)
return LLMUsage.empty_usage()
def build_workflow_tool_container_payload(
self,
*,
tool_runtime: ToolRuntimeHandle,
tool_parameters: Mapping[str, Any],
inputs_for_log: Mapping[str, Any],
workflow_call_depth: int,
) -> WorkflowToolContainerPayload:
"""Prepare a serializable request for Engine-owned Workflow Tool execution."""
from core.tools.workflow_as_tool.tool import WorkflowTool
tool = self._binding_from_handle(tool_runtime).tool
if not isinstance(tool, WorkflowTool):
raise ToolRuntimeResolutionError("resolved tool is not a Workflow Tool")
inputs, system_files = tool.prepare_container_inputs(tool_parameters)
json_inputs = WorkflowRuntimeTypeConverter().to_json_encodable(
{
"inputs": inputs,
"system_files": system_files,
"inputs_for_log": dict(inputs_for_log),
}
)
return WorkflowToolContainerPayload(
source_app_id=tool.workflow_app_id,
source_workflow_id=tool.workflow_id,
source_workflow_version=tool.version,
inputs=json_inputs["inputs"],
system_files=json_inputs["system_files"],
inputs_for_log=json_inputs["inputs_for_log"],
call_depth=workflow_call_depth + 1,
)
def resolve_provider_icons(
self,
*,
@@ -1242,3 +1287,9 @@ def build_dify_llm_file_saver(
file_reference_factory=DifyFileReferenceFactory(run_context),
http_client=http_client,
)
def build_knowledge_fs_node_dependencies() -> dict[str, object]:
"""Resolve the retrieval capabilities registered by the application composition root."""
factory = cast(Callable[[], dict[str, object]], current_app.extensions["knowledge_fs_node_dependencies"])
return factory()