From d9f7f658be0f995d997d04917384786449e9f5dc Mon Sep 17 00:00:00 2001 From: Willem Jiang Date: Sun, 26 Apr 2026 11:12:42 +0800 Subject: [PATCH] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../harness/deerflow/agents/middlewares/memory_middleware.py | 4 ++-- backend/packages/harness/deerflow/sandbox/tools.py | 4 +++- .../harness/deerflow/tools/builtins/present_file_tool.py | 4 +++- backend/packages/harness/deerflow/utils/runtime.py | 2 ++ backend/tests/test_runtime_utils.py | 3 ++- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/backend/packages/harness/deerflow/agents/middlewares/memory_middleware.py b/backend/packages/harness/deerflow/agents/middlewares/memory_middleware.py index 8a7b92208..f17dbd402 100644 --- a/backend/packages/harness/deerflow/agents/middlewares/memory_middleware.py +++ b/backend/packages/harness/deerflow/agents/middlewares/memory_middleware.py @@ -57,10 +57,10 @@ class MemoryMiddleware(AgentMiddleware[MemoryMiddlewareState]): if not config.enabled: return None - # Get thread ID from runtime context + # Resolve thread ID from the runtime or configured fallback sources thread_id = get_thread_id(runtime) if not thread_id: - logger.debug("No thread_id in context, skipping memory update") + logger.debug("No thread_id could be resolved from runtime/config, skipping memory update") return None # Get messages from state diff --git a/backend/packages/harness/deerflow/sandbox/tools.py b/backend/packages/harness/deerflow/sandbox/tools.py index 86c0fef8c..41e5afe88 100644 --- a/backend/packages/harness/deerflow/sandbox/tools.py +++ b/backend/packages/harness/deerflow/sandbox/tools.py @@ -854,7 +854,9 @@ def ensure_sandbox_initialized(runtime: ToolRuntime[ContextT, ThreadState] | Non # Lazy acquisition: get thread_id and acquire sandbox thread_id = get_thread_id(runtime) if thread_id is None: - raise SandboxRuntimeError("Thread ID not available in runtime context") + raise SandboxRuntimeError( + "Thread ID not available in runtime context, runtime config, or LangGraph config" + ) provider = get_sandbox_provider() sandbox_id = provider.acquire(thread_id) diff --git a/backend/packages/harness/deerflow/tools/builtins/present_file_tool.py b/backend/packages/harness/deerflow/tools/builtins/present_file_tool.py index 743e72018..a6f5e8cf4 100644 --- a/backend/packages/harness/deerflow/tools/builtins/present_file_tool.py +++ b/backend/packages/harness/deerflow/tools/builtins/present_file_tool.py @@ -36,7 +36,9 @@ def _normalize_presented_filepath( thread_id = get_thread_id(runtime) if not thread_id: - raise ValueError("Thread ID is not available in runtime context or runtime config") + raise ValueError( + "Thread ID is not available in runtime context, runtime config, or LangGraph thread-local config" + ) thread_data = runtime.state.get("thread_data") or {} outputs_path = thread_data.get("outputs_path") diff --git a/backend/packages/harness/deerflow/utils/runtime.py b/backend/packages/harness/deerflow/utils/runtime.py index 84776b3d9..28977f3b1 100644 --- a/backend/packages/harness/deerflow/utils/runtime.py +++ b/backend/packages/harness/deerflow/utils/runtime.py @@ -83,6 +83,8 @@ def get_thread_id(runtime: Any | None) -> str | None: if thread_id: return thread_id except RuntimeError: + # Expected when not running inside a LangGraph runnable context (e.g., unit tests). + # In that case, thread_id cannot be resolved from thread-local config, so fall through. pass return None diff --git a/backend/tests/test_runtime_utils.py b/backend/tests/test_runtime_utils.py index 2f6cb5a11..35ec19a60 100644 --- a/backend/tests/test_runtime_utils.py +++ b/backend/tests/test_runtime_utils.py @@ -45,7 +45,8 @@ class TestGetThreadId: def test_returns_none_when_get_config_raises_runtime_error(self): runtime = SimpleNamespace(context=None, config={}) - assert get_thread_id(runtime) is None + with patch("langgraph.config.get_config", side_effect=RuntimeError): + assert get_thread_id(runtime) is None def test_handles_object_without_context_or_config(self): runtime = SimpleNamespace()