From 2b7e08a5e190eebc1b82e224eac3632cf5dfe063 Mon Sep 17 00:00:00 2001 From: jordanchendev Date: Wed, 17 Jun 2026 12:38:40 -0700 Subject: [PATCH] fix: send correct field names for sandbox input files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge https://github.com/google/adk-python/pull/5958 ## Problem `AgentEngineSandboxCodeExecutor` was building the input-file payload with incorrect JSON field names: | Code sent | API expects | |------------|-------------| | `contents` | `content` | | `mimeType` | `mime_type` | This caused all input files to be silently unreadable inside the sandbox, producing errors such as: ``` pandas.errors.EmptyDataError: No columns to parse from file ``` Fixes #3690 ## Changes - `src/google/adk/code_executors/agent_engine_sandbox_code_executor.py` — rename the two dict keys in the `input_data['files']` list comprehension. - `tests/unittests/code_executors/test_agent_engine_sandbox_code_executor.py` — add regression test `test_execute_code_sends_correct_field_names_for_input_files` that verifies the correct keys are sent to the API. ## Testing plan - [x] New regression test added that asserts `content` and `mime_type` are used (was failing before the fix, passes after). - [x] All existing tests in the file still pass. ### pytest output ``` uv run --extra test python -m pytest tests/unittests/code_executors/test_agent_engine_sandbox_code_executor.py -v ======================== 11 passed, 5 warnings in 2.04s ======================== ``` ### pre-commit ``` pre-commit run --files src/google/adk/code_executors/agent_engine_sandbox_code_executor.py \ tests/unittests/code_executors/test_agent_engine_sandbox_code_executor.py isort....................................................................Passed pyink....................................................................Passed addlicense...............................................................Passed ``` Co-authored-by: Kathy Wu COPYBARA_INTEGRATE_REVIEW=https://github.com/google/adk-python/pull/5958 from jordanchendev:fix/3690-sandbox-input-file-field-names eefe91165fb5ea156b6e473adb329ce12d13616f PiperOrigin-RevId: 933868136 --- .../agent_engine_sandbox_code_executor.py | 2 +- ...test_agent_engine_sandbox_code_executor.py | 50 ++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) 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 e56e3926..7bdbf366 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 @@ -181,7 +181,7 @@ class AgentEngineSandboxCodeExecutor(BaseCodeExecutor): { 'name': f.name, 'content': f.content, - 'mimeType': f.mime_type, + 'mime_type': f.mime_type, } for f in code_execution_input.input_files ] 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 bfab0d30..a0ec2a3c 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 @@ -157,7 +157,7 @@ class TestAgentEngineSandboxCodeExecutor: ) sent_files = call_kwargs["input_data"]["files"] assert sent_files == [ - {"name": "data.csv", "content": "a,b,c", "mimeType": "text/csv"} + {"name": "data.csv", "content": "a,b,c", "mime_type": "text/csv"} ] @patch("vertexai.Client") @@ -355,6 +355,54 @@ class TestAgentEngineSandboxCodeExecutor: input_data={"code": 'print("hello world")'}, ) + @patch("vertexai.Client") + def test_execute_code_sends_correct_field_names_for_input_files( + self, + mock_vertexai_client, + mock_invocation_context, + ): + """Input files are sent with 'content' and 'mime_type' keys (not 'contents'/'mimeType').""" + 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": "", "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="import pandas as pd; df = pd.read_csv('data.csv')", + input_files=[ + File( + name="data.csv", content=b"col1,col2\n1,2", mime_type="text/csv" + ) + ], + ) + + executor.execute_code(mock_invocation_context, code_input) + + mock_api_client.agent_engines.sandboxes.execute_code.assert_called_once_with( + name="projects/123/locations/us-central1/reasoningEngines/456/sandboxEnvironments/789", + input_data={ + "code": "import pandas as pd; df = pd.read_csv('data.csv')", + "files": [{ + "name": "data.csv", + "content": b"col1,col2\n1,2", + "mime_type": "text/csv", + }], + }, + ) + def test_init_with_agent_engine_resource_name(self): """Tests init when only agent_engine_resource_name is provided.""" agent_engine_name = (