fix(workflow): guard on_tool_execution stdout traces behind DEBUG (#38200)

This commit is contained in:
Bond Zhu 2026-06-30 15:19:48 +08:00 committed by GitHub
parent 102e1ede6e
commit 03d59dba47
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 49 additions and 10 deletions

View File

@ -1,6 +1,7 @@
from collections.abc import Generator, Iterable, Mapping
from typing import Any
from configs import dify_config
from core.callback_handler.agent_tool_callback_handler import DifyAgentCallbackHandler, print_text
from core.ops.ops_trace_manager import TraceQueueManager
from core.tools.entities.tool_entities import ToolInvokeMessage
@ -19,8 +20,9 @@ class DifyWorkflowCallbackHandler(DifyAgentCallbackHandler):
trace_manager: TraceQueueManager | None = None,
) -> Generator[ToolInvokeMessage, None, None]:
for tool_output in tool_outputs:
print_text("\n[on_tool_execution]\n", color=self.color)
print_text("Tool: " + tool_name + "\n", color=self.color)
print_text("Outputs: " + tool_output.model_dump_json()[:1000] + "\n", color=self.color)
print_text("\n")
if dify_config.DEBUG:
print_text("\n[on_tool_execution]\n", color=self.color)
print_text("Tool: " + tool_name + "\n", color=self.color)
print_text("Outputs: " + tool_output.model_dump_json()[:1000] + "\n", color=self.color)
print_text("\n")
yield tool_output

View File

@ -32,8 +32,16 @@ def mock_print_text(mocker: MockerFixture):
return mocker.patch("core.callback_handler.workflow_tool_callback_handler.print_text")
@pytest.fixture
def enable_debug(mocker: MockerFixture):
"""Force DEBUG on so the handler emits its verbose stdout traces."""
mocker.patch("core.callback_handler.workflow_tool_callback_handler.dify_config.DEBUG", True)
class TestDifyWorkflowCallbackHandler:
def test_on_tool_execution_single_output_success(self, handler: DifyWorkflowCallbackHandler, mock_print_text):
def test_on_tool_execution_single_output_success(
self, handler: DifyWorkflowCallbackHandler, mock_print_text, enable_debug
):
# Arrange
tool_name = "test_tool"
tool_inputs = {"a": 1}
@ -63,7 +71,9 @@ class TestDifyWorkflowCallbackHandler:
]
)
def test_on_tool_execution_multiple_outputs(self, handler: DifyWorkflowCallbackHandler, mock_print_text):
def test_on_tool_execution_multiple_outputs(
self, handler: DifyWorkflowCallbackHandler, mock_print_text, enable_debug
):
# Arrange
tool_name = "multi_tool"
outputs = [
@ -101,6 +111,29 @@ class TestDifyWorkflowCallbackHandler:
assert results == []
mock_print_text.assert_not_called()
def test_on_tool_execution_skips_print_when_debug_disabled(
self, handler: DifyWorkflowCallbackHandler, mock_print_text, mocker: MockerFixture
):
"""When DEBUG is off, outputs are still yielded but nothing is printed
and model_dump_json() is never invoked."""
# Arrange
mocker.patch("core.callback_handler.workflow_tool_callback_handler.dify_config.DEBUG", False)
message = MagicMock()
# Act
results = list(
handler.on_tool_execution(
tool_name="quiet_tool",
tool_inputs={},
tool_outputs=[message],
)
)
# Assert
assert results == [message]
mock_print_text.assert_not_called()
message.model_dump_json.assert_not_called()
@pytest.mark.parametrize(
("invalid_outputs", "expected_exception"),
[
@ -110,7 +143,7 @@ class TestDifyWorkflowCallbackHandler:
],
)
def test_on_tool_execution_invalid_outputs_type(
self, handler: DifyWorkflowCallbackHandler, invalid_outputs, expected_exception
self, handler: DifyWorkflowCallbackHandler, invalid_outputs, expected_exception, enable_debug
):
# Arrange
tool_name = "invalid_tool"
@ -125,7 +158,9 @@ class TestDifyWorkflowCallbackHandler:
)
)
def test_on_tool_execution_long_json_truncation(self, handler: DifyWorkflowCallbackHandler, mock_print_text):
def test_on_tool_execution_long_json_truncation(
self, handler: DifyWorkflowCallbackHandler, mock_print_text, enable_debug
):
# Arrange
tool_name = "long_json_tool"
long_json = "x" * 1500
@ -147,7 +182,9 @@ class TestDifyWorkflowCallbackHandler:
color="blue",
)
def test_on_tool_execution_model_dump_json_exception(self, handler: DifyWorkflowCallbackHandler, mock_print_text):
def test_on_tool_execution_model_dump_json_exception(
self, handler: DifyWorkflowCallbackHandler, mock_print_text, enable_debug
):
# Arrange
tool_name = "exception_tool"
bad_message = MagicMock()
@ -167,7 +204,7 @@ class TestDifyWorkflowCallbackHandler:
assert mock_print_text.call_count >= 2
def test_on_tool_execution_none_message_id_and_trace_manager(
self, handler: DifyWorkflowCallbackHandler, mock_print_text
self, handler: DifyWorkflowCallbackHandler, mock_print_text, enable_debug
):
# Arrange
tool_name = "optional_params_tool"