From 2f03c9acab3e41e34fbea540b9b9120b3ac716bd Mon Sep 17 00:00:00 2001 From: Thapelo Date: Sat, 30 May 2026 20:32:19 +0200 Subject: [PATCH 1/2] fix: use correct 'content' key in AgentEngineSandboxCodeExecutor input files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AgentEngineSandboxCodeExecutor builds input file payloads with key 'contents' (plural), but the Vertex AI SDK reads 'content' (singular). This causes file.get('content', b'') to always return empty bytes — all input files are silently created as zero bytes in the sandbox with SUCCESS status returned. Fixes the same root cause as PR #5505 which fixed this in other files but missed agent_engine_sandbox_code_executor.py. Ref: #5500, #5505, #5824 --- .../adk/code_executors/agent_engine_sandbox_code_executor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/google/adk/code_executors/agent_engine_sandbox_code_executor.py b/src/google/adk/code_executors/agent_engine_sandbox_code_executor.py index c9215d3c86..e56e3926b5 100644 --- a/src/google/adk/code_executors/agent_engine_sandbox_code_executor.py +++ b/src/google/adk/code_executors/agent_engine_sandbox_code_executor.py @@ -180,7 +180,7 @@ def execute_code( input_data['files'] = [ { 'name': f.name, - 'contents': f.content, + 'content': f.content, 'mimeType': f.mime_type, } for f in code_execution_input.input_files From 43b2601ef986e1a5bf2ec2024086c08ed04789b0 Mon Sep 17 00:00:00 2001 From: Thapelo Date: Sat, 30 May 2026 20:45:03 +0200 Subject: [PATCH 2/2] test: add regression test for input_files content key (#5912) Verifies that AgentEngineSandboxCodeExecutor sends input_files with the 'content' key (singular), matching what the Vertex AI Sandbox API expects. Without this fix, file.get('content', b'') returns empty bytes and all input files are silently created empty. Ref: #5500, #5505, #5824 --- ...test_agent_engine_sandbox_code_executor.py | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/tests/unittests/code_executors/test_agent_engine_sandbox_code_executor.py b/tests/unittests/code_executors/test_agent_engine_sandbox_code_executor.py index 32897941dd..c6432ffa99 100644 --- a/tests/unittests/code_executors/test_agent_engine_sandbox_code_executor.py +++ b/tests/unittests/code_executors/test_agent_engine_sandbox_code_executor.py @@ -20,6 +20,7 @@ from google.adk.agents.invocation_context import InvocationContext from google.adk.code_executors.agent_engine_sandbox_code_executor import AgentEngineSandboxCodeExecutor from google.adk.code_executors.code_execution_utils import CodeExecutionInput +from google.adk.code_executors.code_execution_utils import File as InputFile from google.adk.sessions.session import Session import pytest @@ -125,6 +126,63 @@ def test_execute_code_success( input_data={"code": 'print("hello world")'}, ) + @patch("vertexai.Client") + def test_execute_code_input_files_content_key( + self, + mock_vertexai_client, + mock_invocation_context, + ): + """Tests that input_files are sent with 'content' (singular), not 'contents'. + + Regression test for https://github.com/google/adk-python/issues/5500. + The Vertex AI Sandbox API reads file.get("content", b""), so using the + key "contents" silently creates empty files. + """ + mock_api_client = MagicMock() + mock_vertexai_client.return_value = mock_api_client + mock_response = MagicMock() + mock_json_output = MagicMock() + mock_json_output.mime_type = "application/json" + mock_json_output.data = json.dumps( + {"msg_out": "ok", "msg_err": ""} + ).encode("utf-8") + mock_json_output.metadata = None + mock_response.outputs = [mock_json_output] + mock_api_client.agent_engines.sandboxes.execute_code.return_value = ( + mock_response + ) + + executor = AgentEngineSandboxCodeExecutor( + sandbox_resource_name="projects/123/locations/us-central1/reasoningEngines/456/sandboxEnvironments/789" + ) + code_input = CodeExecutionInput( + code='print("hello world")', + input_files=[ + InputFile( + name="test.txt", + content=b"hello world", + mime_type="text/plain", + ) + ], + ) + executor.execute_code(mock_invocation_context, code_input) + + # Verify the API was called with 'content' key, NOT 'contents' + expected_input_data = { + "code": 'print("hello world")', + "files": [ + { + "name": "test.txt", + "content": b"hello world", + "mimeType": "text/plain", + } + ], + } + mock_api_client.agent_engines.sandboxes.execute_code.assert_called_once_with( + name="projects/123/locations/us-central1/reasoningEngines/456/sandboxEnvironments/789", + input_data=expected_input_data, + ) + @patch("vertexai.Client") def test_execute_code_recreates_sandbox_when_get_returns_none( self,