Skip to content

Commit 9a452cc

Browse files
vertex-sdk-botcopybara-github
authored andcommitted
feat: GenAI SDK client - Update input handling inside code execution sandbox
PiperOrigin-RevId: 818790766
1 parent 71a7832 commit 9a452cc

File tree

2 files changed

+57
-10
lines changed

2 files changed

+57
-10
lines changed

tests/unit/vertexai/genai/replays/test_execute_code_agent_engine_sandbox.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,30 @@ def test_execute_code_sandbox(client):
3333
config=types.CreateAgentEngineSandboxConfig(display_name="test_sandbox"),
3434
)
3535
assert isinstance(operation, types.AgentEngineSandboxOperation)
36+
37+
code = """
38+
with open("test.txt", "r") as input:
39+
with open("output.txt", "w") as output_txt:
40+
for line in input:
41+
output_txt.write(line)
42+
"""
3643
input_data = {
37-
"language": "python",
38-
"code": 'with open("hello.txt","w") as file:\n file.write("Hello, world!")',
44+
"code": code,
45+
"files": [
46+
{
47+
"name": "test.txt",
48+
"mimeType": "text/plain",
49+
"content": b"Hello, world!",
50+
}
51+
],
3952
}
4053
response = client.agent_engines.sandboxes.execute_code(
4154
name=operation.response.name,
4255
input_data=input_data,
4356
)
4457
assert response.outputs[0].mime_type == "application/json"
58+
assert response.outputs[1].data == b"Hello, world!"
59+
assert response.outputs[1].metadata.attributes.get("file_name") == b"output.txt"
4560

4661

4762
pytestmark = pytest_helper.setup(

vertexai/_genai/sandboxes.py

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515

1616
# Code generated by the Google Gen AI SDK generator DO NOT EDIT.
1717

18-
import base64
1918
import functools
2019
import json
2120
import logging
21+
import mimetypes
2222
from typing import Any, Iterator, Optional, Union
2323
from urllib.parse import urlencode
2424

@@ -618,20 +618,52 @@ def execute_code(
618618
Returns:
619619
ExecuteSandboxEnvironmentResponse: The response from executing the code.
620620
"""
621-
json_string = json.dumps(input_data)
622-
623-
base64_bytes = base64.b64encode(json_string.encode("utf-8"))
624-
base64_string = base64_bytes.decode("utf-8")
621+
input_chunks = []
622+
623+
if input_data.get("code") is not None:
624+
code = input_data.get("code", "")
625+
json_code = json.dumps({"code": code}).encode("utf-8")
626+
input_chunks.append(
627+
types.Chunk(
628+
mime_type="application/json",
629+
data=json_code,
630+
)
631+
)
625632

626-
# Only single JSON input is supported for now.
627-
inputs = [{"mime_type": "application/json", "data": base64_string}]
633+
for file in input_data.get("files", []):
634+
file_name = file.get("name", "")
635+
input_chunks.append(
636+
types.Chunk(
637+
mime_type=file.get("mimeType", ""),
638+
data=file.get("content", b""),
639+
metadata={"attributes": {"file_name": file_name.encode("utf-8")}},
640+
)
641+
)
628642

629643
response = self._execute_code(
630644
name=name,
631-
inputs=inputs,
645+
inputs=input_chunks,
632646
config=config,
633647
)
634648

649+
output_chunks = []
650+
for output in response.outputs:
651+
if output.mime_type is None:
652+
# if mime_type is not available, try to guess the mime_type from the file_name.
653+
if (
654+
output.metadata is not None
655+
and output.metadata.attributes is not None
656+
):
657+
file_name = output.metadata.attributes.get("file_name", b"").decode(
658+
"utf-8"
659+
)
660+
mime_type, _ = mimetypes.guess_type(file_name)
661+
output.mime_type = mime_type
662+
663+
output_chunks.append(output)
664+
665+
response = types.ExecuteSandboxEnvironmentResponse(outputs=output_chunks)
666+
635667
return response
636668

637669
def get(

0 commit comments

Comments
 (0)