From 878cf0a48767131677a6dd065de5524e91e3c984 Mon Sep 17 00:00:00 2001 From: Huixin615 Date: Mon, 8 Jun 2026 00:57:58 +0800 Subject: [PATCH] fix(middleware): address Copilot review feedback on sandbox externalization - Make get_sandbox_provider() lookup best-effort in _budget_content: only query when outputs_path or sandbox is available, and fall back to inline truncation if provider initialization raises rather than propagating the error. A resolved sandbox instance is sufficient on its own to take the non-mounted externalization branch. - Strict-match the sandbox post-write validation echo (check.strip() == 'OK') to avoid false positives if execute_command ever surfaces unrelated stdout/stderr containing 'OK' as a substring. Refs: #3417 --- .../middlewares/tool_output_budget_middleware.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/backend/packages/harness/deerflow/agents/middlewares/tool_output_budget_middleware.py b/backend/packages/harness/deerflow/agents/middlewares/tool_output_budget_middleware.py index e8bc3c0d2..df95a22e0 100644 --- a/backend/packages/harness/deerflow/agents/middlewares/tool_output_budget_middleware.py +++ b/backend/packages/harness/deerflow/agents/middlewares/tool_output_budget_middleware.py @@ -181,7 +181,7 @@ def _externalize_to_sandbox( # to create the directory, and write_file backends differ. Refuse to # hand the model an unreadable read_file path. check = sandbox.execute_command(f"test -s {shlex.quote(virtual_path)} && echo OK || echo MISSING") - if not isinstance(check, str) or "OK" not in check: + if not isinstance(check, str) or check.strip() != "OK": logger.warning( "Sandbox externalize validation failed: path=%s, check=%r", virtual_path, @@ -340,8 +340,13 @@ def _budget_content( if threshold > 0 and len(content) > threshold: virtual_path: str | None = None - provider = get_sandbox_provider() - if getattr(provider, "uses_thread_data_mounts", False): + provider = None + if outputs_path or sandbox is not None: + try: + provider = get_sandbox_provider() + except Exception: + logger.exception("Failed to get sandbox provider for tool-output externalization; falling back to inline truncation") + if provider is not None and getattr(provider, "uses_thread_data_mounts", False): # Host-mounted sandbox: the host outputs path is bind-mounted into # the sandbox at the same virtual path, so writing host-side is # equivalent to writing sandbox-side. Preserve the original @@ -355,8 +360,6 @@ def _budget_content( storage_subdir=config.storage_subdir, ) elif sandbox is not None: - # Non-mounted (remote) sandbox: write into the sandbox itself so - # the model's read_file tool can read it back. Issue #3416. virtual_path = _externalize_to_sandbox( content, tool_name=tool_name,