Skip to content

Commit 4ce56e1

Browse files
committed
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
1 parent 4bc52af commit 4ce56e1

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

tests/unittests/code_executors/test_agent_engine_sandbox_code_executor.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from google.adk.agents.invocation_context import InvocationContext
2121
from google.adk.code_executors.agent_engine_sandbox_code_executor import AgentEngineSandboxCodeExecutor
2222
from google.adk.code_executors.code_execution_utils import CodeExecutionInput
23+
from google.adk.code_executors.code_execution_utils import File as InputFile
2324
from google.adk.sessions.session import Session
2425
import pytest
2526

@@ -125,6 +126,63 @@ def test_execute_code_success(
125126
input_data={"code": 'print("hello world")'},
126127
)
127128

129+
@patch("vertexai.Client")
130+
def test_execute_code_input_files_content_key(
131+
self,
132+
mock_vertexai_client,
133+
mock_invocation_context,
134+
):
135+
"""Tests that input_files are sent with 'content' (singular), not 'contents'.
136+
137+
Regression test for https://github.com/google/adk-python/issues/5500.
138+
The Vertex AI Sandbox API reads file.get("content", b""), so using the
139+
key "contents" silently creates empty files.
140+
"""
141+
mock_api_client = MagicMock()
142+
mock_vertexai_client.return_value = mock_api_client
143+
mock_response = MagicMock()
144+
mock_json_output = MagicMock()
145+
mock_json_output.mime_type = "application/json"
146+
mock_json_output.data = json.dumps(
147+
{"msg_out": "ok", "msg_err": ""}
148+
).encode("utf-8")
149+
mock_json_output.metadata = None
150+
mock_response.outputs = [mock_json_output]
151+
mock_api_client.agent_engines.sandboxes.execute_code.return_value = (
152+
mock_response
153+
)
154+
155+
executor = AgentEngineSandboxCodeExecutor(
156+
sandbox_resource_name="projects/123/locations/us-central1/reasoningEngines/456/sandboxEnvironments/789"
157+
)
158+
code_input = CodeExecutionInput(
159+
code='print("hello world")',
160+
input_files=[
161+
InputFile(
162+
name="test.txt",
163+
content=b"hello world",
164+
mime_type="text/plain",
165+
)
166+
],
167+
)
168+
executor.execute_code(mock_invocation_context, code_input)
169+
170+
# Verify the API was called with 'content' key, NOT 'contents'
171+
expected_input_data = {
172+
"code": 'print("hello world")',
173+
"files": [
174+
{
175+
"name": "test.txt",
176+
"content": b"hello world",
177+
"mimeType": "text/plain",
178+
}
179+
],
180+
}
181+
mock_api_client.agent_engines.sandboxes.execute_code.assert_called_once_with(
182+
name="projects/123/locations/us-central1/reasoningEngines/456/sandboxEnvironments/789",
183+
input_data=expected_input_data,
184+
)
185+
128186
@patch("vertexai.Client")
129187
def test_execute_code_recreates_sandbox_when_get_returns_none(
130188
self,

0 commit comments

Comments
 (0)