Skip to content

fix(code_executors): correct sandbox JSON field names for stdout & input files#4516

Open
jbets4 wants to merge 1 commit intogoogle:mainfrom
jbets4:open-source-contribution
Open

fix(code_executors): correct sandbox JSON field names for stdout & input files#4516
jbets4 wants to merge 1 commit intogoogle:mainfrom
jbets4:open-source-contribution

Conversation

@jbets4
Copy link

@jbets4 jbets4 commented Feb 17, 2026

#3690

- Closes: #3690

Problem:
the AgentEngineSandboxCodeExecutor file was incorrectly using JSON field names when sending input files and when parsing the sandbox JSON response. This causes input files to be unreadable in the sandbox and caused stdout/stderr to appear empty.

Solution:

  • Updated input file payload keys to content and mime_type (previously were contents and mimeType) so sandbox API can correctly read files
  • Updated JSON response parsing to read both msg_out / msg_err (also implemented backwards compatibility for stdout / stderr)

Testing Plan

  • I verified changes by adding unit tests for AgentEngineSandboxCodeExecutor. These tests mock sandbox API responses to ensure msg_out and msg_err fields are parsed into stdout and stderr respectively, and verify input files are sent using correct payload keys (content & mime_type). all unit test were run locally using pytest and passed successfully.

Summary of results below
======================== 5 passed, 3 warnings in 4.28s =========================
PASSED [ 20%]PASSED [ 40%]PASSED [ 60%]PASSED [ 80%]PASSED [100%]
Process finished with exit code 0

Manual E2E test are beyond the scope for this change.

Checklist

  • [ X] I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • [ X] I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • [ X] New and existing unit tests pass locally with my changes.
  • [] I have manually tested my changes end-to-end.
  • [] Any dependent changes have been merged and published in downstream modules.

@google-cla
Copy link

google-cla bot commented Feb 17, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @jbets4, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses critical issues in the AgentEngineSandboxCodeExecutor that prevented proper communication with the sandbox API. By rectifying incorrect JSON field names for input files and enhancing the parsing of sandbox responses, it ensures that input files are correctly read and that standard output and error messages are accurately captured, significantly improving the reliability of code execution within the sandbox environment.

Highlights

  • Sandbox API Payload Correction: Corrected the JSON field names for input files sent to the sandbox API from 'contents' to 'content' and 'mimeType' to 'mime_type' to ensure files are correctly processed.
  • Sandbox Output Parsing Enhancement: Updated the parsing logic for sandbox API responses to prioritize 'msg_out' and 'msg_err' fields for standard output and error, while maintaining backward compatibility with 'stdout' and 'stderr'.
  • Improved Unit Test Coverage: Added new unit tests to specifically verify the correct parsing of sandbox output messages and the proper usage of payload keys for input files, ensuring the fixes are robust.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/google/adk/code_executors/agent_engine_sandbox_code_executor.py
    • Updated input file payload keys from 'contents' to 'content' and 'mimeType' to 'mime_type' to match sandbox API expectations.
    • Modified JSON response parsing to first check for 'msg_out' and 'msg_err' for stdout/stderr, with a fallback to 'stdout' and 'stderr' for backward compatibility.
  • tests/unittests/code_executors/test_agent_engine_sandbox_code_executor.py
    • Imported the File class for use in new test cases.
    • Refactored the existing test_execute_code_success into two new, more focused tests: test_execute_code_parses_msg_out_msg_err and test_execute_code_input_files_use_correct_payload_keys.
    • Added a new test to verify that the executor correctly parses 'msg_out' and 'msg_err' from sandbox responses.
    • Added a new test to confirm that input files are sent with the correct 'content' and 'mime_type' payload keys.
Activity
  • The author identified a problem where the AgentEngineSandboxCodeExecutor was using incorrect JSON field names, leading to unreadable input files and empty stdout/stderr.
  • The author implemented a solution by updating input file payload keys and adjusting JSON response parsing.
  • The author added unit tests for AgentEngineSandboxCodeExecutor to mock sandbox API responses and verify correct parsing and payload key usage.
  • All new and existing unit tests were run locally using pytest and passed successfully.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@adk-bot adk-bot added the core [Component] This issue is related to the core interface and implementation label Feb 17, 2026
@adk-bot
Copy link
Collaborator

adk-bot commented Feb 17, 2026

Response from ADK Triaging Agent

Hello @jbets4, thank you for your contribution!

Before we can merge this pull request, you'll need to sign the Contributor License Agreement (CLA). You can find more information at https://cla.developers.google.com/.

Thanks!

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request correctly fixes a bug where incorrect JSON field names were used for sandbox code execution, affecting both input file uploads and output parsing. The changes to use content/mime_type for inputs and parse msg_out/msg_err for outputs (while maintaining backward compatibility) are well-implemented. The new unit tests are a great addition and validate the core fixes. However, I've noted a regression in test coverage due to the removal of a previous test case. My review includes a suggestion to add back tests for output file parsing and backward compatibility to ensure the code remains robust.

Comment on lines 62 to +155
@patch("vertexai.Client")
def test_execute_code_success(
self,
mock_vertexai_client,
mock_invocation_context,
def test_execute_code_parses_msg_out_msg_err(
self,
mock_vertexai_client,
mock_invocation_context,
):
# Setup Mocks
# Setup mocks
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(
{"stdout": "hello world", "stderr": ""}
{"msg_out": "hello", "msg_err": "boom"}
).encode("utf-8")
mock_json_output.metadata = None
mock_response.outputs = [mock_json_output]

mock_file_output = MagicMock()
mock_file_output.mime_type = "text/plain"
mock_file_output.data = b"file content"
mock_file_output.metadata = MagicMock()
mock_file_output.metadata.attributes = {"file_name": b"file.txt"}

mock_png_file_output = MagicMock()
mock_png_file_output.mime_type = "image/png"
sample_png_bytes = b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89"
mock_png_file_output.data = sample_png_bytes
mock_png_file_output.metadata = MagicMock()
mock_png_file_output.metadata.attributes = {"file_name": b"file.png"}

mock_response.outputs = [
mock_json_output,
mock_file_output,
mock_png_file_output,
]
mock_api_client.agent_engines.sandboxes.execute_code.return_value = (
mock_response
mock_response
)

# Execute
executor = AgentEngineSandboxCodeExecutor(
sandbox_resource_name="projects/123/locations/us-central1/reasoningEngines/456/sandboxEnvironments/789"
sandbox_resource_name=(
"projects/123/locations/us-central1/"
"reasoningEngines/456/sandboxEnvironments/789"
)
)
result = executor.execute_code(
mock_invocation_context,
CodeExecutionInput(code='print("x")'),
)
code_input = CodeExecutionInput(code='print("hello world")')
result = executor.execute_code(mock_invocation_context, code_input)

# Assert
assert result.stdout == "hello world"
assert not result.stderr
assert result.output_files[0].mime_type == "text/plain"
assert result.output_files[0].content == b"file content"

assert result.output_files[0].name == "file.txt"
assert result.output_files[1].mime_type == "image/png"
assert result.output_files[1].name == "file.png"
assert result.output_files[1].content == sample_png_bytes
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": 'print("hello world")'},
assert result.stdout == "hello"
assert result.stderr == "boom"


@patch("vertexai.Client")
def test_execute_code_input_files_use_correct_payload_keys(
self,
mock_vertexai_client,
mock_invocation_context,
):
# Setup mocks
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": ""}).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
)

# Execute with input files
executor = AgentEngineSandboxCodeExecutor(
sandbox_resource_name=(
"projects/123/locations/us-central1/"
"reasoningEngines/456/sandboxEnvironments/789"
)
)
code_input = CodeExecutionInput(
code='print("x")',
input_files=[
File(
name="data.csv",
content=b"a,b\n1,2\n",
mime_type="text/csv",
)
],
)

executor.execute_code(mock_invocation_context, code_input)

# Assert payload keys
call_kwargs = (
mock_api_client.agent_engines.sandboxes.execute_code.call_args.kwargs
)
files = call_kwargs["input_data"]["files"]
f0 = files[0]

assert f0["content"] == b"a,b\n1,2\n"
assert f0["mime_type"] == "text/csv"
assert "contents" not in f0
assert "mimeType" not in f0


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While the new tests are excellent for verifying the primary fixes, the removal of the original test_execute_code_success has led to a loss of test coverage for a couple of important scenarios:

  1. Backward Compatibility: There is no longer a test to ensure that responses using the old stdout and stderr keys are still parsed correctly.
  2. Output File Parsing: The logic for parsing output files from the sandbox response is no longer covered by tests.

To prevent future regressions, it would be beneficial to add tests for these cases. Here are some suggestions:

@patch("vertexai.Client")
def test_execute_code_parses_stdout_stderr_for_backward_compatibility(
        self,
        mock_vertexai_client,
        mock_invocation_context,
):
    # Setup mocks
    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(
        {"stdout": "old hello", "stderr": "old boom"}
    ).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

    # Execute
    executor = AgentEngineSandboxCodeExecutor(
        sandbox_resource_name=(
            "projects/123/locations/us-central1/"
            "reasoningEngines/456/sandboxEnvironments/789"
        )
    )
    result = executor.execute_code(
        mock_invocation_context,
        CodeExecutionInput(code='print("x")'),
    )

    # Assert
    assert result.stdout == "old hello"
    assert result.stderr == "old boom"

@patch("vertexai.Client")
def test_execute_code_parses_output_files(
        self,
        mock_vertexai_client,
        mock_invocation_context,
):
    # Setup mocks
    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": ""}).encode("utf-8")
    mock_json_output.metadata = None

    mock_file_output = MagicMock()
    mock_file_output.mime_type = "text/plain"
    mock_file_output.data = b"file content"
    mock_file_output.metadata = MagicMock()
    mock_file_output.metadata.attributes = {"file_name": b"file.txt"}

    mock_response.outputs = [mock_json_output, mock_file_output]
    mock_api_client.agent_engines.sandboxes.execute_code.return_value = mock_response

    # Execute
    executor = AgentEngineSandboxCodeExecutor(
        sandbox_resource_name=(
            "projects/123/locations/us-central1/"
            "reasoningEngines/456/sandboxEnvironments/789"
        )
    )
    result = executor.execute_code(
        mock_invocation_context,
        CodeExecutionInput(code='print("x")'),
    )

    # Assert
    assert len(result.output_files) == 1
    assert result.output_files[0].name == "file.txt"
    assert result.output_files[0].content == b"file content"
    assert result.output_files[0].mime_type == "text/plain"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core [Component] This issue is related to the core interface and implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AgentEngineSandboxCodeExecutor uses wrong JSON field names for stdout/stderr

2 participants