Skip to content

Commit f7e718f

Browse files
shawn-yang-googlecopybara-github
authored andcommitted
feat: GenAI SDK client - Support build options in Agent Engine source-based Deployment.
PiperOrigin-RevId: 833525372
1 parent 28499a9 commit f7e718f

File tree

5 files changed

+76
-33
lines changed

5 files changed

+76
-33
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,13 @@ def replays_prefix():
123123
return "test"
124124

125125

126+
@pytest.fixture
127+
def mock_agent_engine_create_path_exists():
128+
"""Mocks os.path.exists to return True."""
129+
with mock.patch("os.path.exists", return_value=True) as mock_exists:
130+
yield mock_exists
131+
132+
126133
@pytest.fixture
127134
def mock_agent_engine_create_base64_encoded_tarball():
128135
"""Mocks the _create_base64_encoded_tarball function."""

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,13 @@ def test_create_with_context_spec(client):
115115
def test_create_with_source_packages(
116116
client,
117117
mock_agent_engine_create_base64_encoded_tarball,
118+
mock_agent_engine_create_path_exists,
118119
):
119120
"""Tests creating an agent engine with source packages."""
120-
with mock_agent_engine_create_base64_encoded_tarball:
121+
with (
122+
mock_agent_engine_create_base64_encoded_tarball,
123+
mock_agent_engine_create_path_exists,
124+
):
121125
agent_engine = client.agent_engines.create(
122126
config={
123127
"display_name": "test-agent-engine-source-packages",

tests/unit/vertexai/genai/test_agent_engines.py

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,10 +1062,42 @@ def test_create_agent_engine_config_with_source_packages(
10621062
== _TEST_AGENT_ENGINE_IDENTITY_TYPE_SERVICE_ACCOUNT
10631063
)
10641064

1065+
@mock.patch.object(
1066+
_agent_engines_utils,
1067+
"_create_base64_encoded_tarball",
1068+
return_value="test_tarball",
1069+
)
1070+
@mock.patch.object(_agent_engines_utils, "_validate_packages_or_raise")
1071+
def test_create_agent_engine_config_with_source_packages_and_build_options(
1072+
self, mock_validate_packages, mock_create_base64_encoded_tarball
1073+
):
1074+
with tempfile.TemporaryDirectory() as tmpdir:
1075+
test_file_path = os.path.join(tmpdir, "main.py")
1076+
with open(test_file_path, "w") as f:
1077+
f.write("app = None")
1078+
build_options = {
1079+
"installation_scripts": ["installation_scripts/install.sh"]
1080+
}
1081+
source_packages = [test_file_path, "installation_scripts/install.sh"]
1082+
mock_validate_packages.return_value = source_packages
1083+
1084+
self.client.agent_engines._create_config(
1085+
mode="create",
1086+
source_packages=source_packages,
1087+
entrypoint_module="main",
1088+
entrypoint_object="app",
1089+
build_options=build_options,
1090+
class_methods=_TEST_AGENT_ENGINE_CLASS_METHODS,
1091+
)
1092+
mock_validate_packages.assert_called_once_with(
1093+
packages=source_packages,
1094+
build_options=build_options,
1095+
)
1096+
10651097
@mock.patch.object(_agent_engines_utils, "_prepare")
1066-
@mock.patch.object(_agent_engines_utils, "_validate_extra_packages_or_raise")
1098+
@mock.patch.object(_agent_engines_utils, "_validate_packages_or_raise")
10671099
def test_create_agent_engine_config_with_build_options(
1068-
self, mock_validate_extra_packages, mock_prepare
1100+
self, mock_validate_packages, mock_prepare
10691101
):
10701102
build_options = {"installation_scripts": ["install.sh"]}
10711103
extra_packages = ["install.sh"]
@@ -1079,8 +1111,8 @@ def test_create_agent_engine_config_with_build_options(
10791111
build_options=build_options,
10801112
)
10811113

1082-
mock_validate_extra_packages.assert_called_once_with(
1083-
extra_packages=extra_packages,
1114+
mock_validate_packages.assert_called_once_with(
1115+
packages=extra_packages,
10841116
build_options=build_options,
10851117
)
10861118

vertexai/_genai/_agent_engines_utils.py

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,42 +1238,40 @@ def _create_base64_encoded_tarball(
12381238
return base64.b64encode(tarball_bytes).decode("utf-8")
12391239

12401240

1241-
def _validate_extra_packages_or_raise(
1241+
def _validate_packages_or_raise(
12421242
*,
1243-
extra_packages: Sequence[str],
1243+
packages: Sequence[str],
12441244
build_options: Optional[Dict[str, Sequence[str]]] = None,
12451245
) -> Sequence[str]:
1246-
"""Tries to validates the extra packages."""
1247-
extra_packages = extra_packages or []
1246+
"""Tries to validates the packages."""
1247+
packages = packages or []
12481248
if build_options and _INSTALLATION_SUBDIR in build_options:
12491249
_validate_installation_scripts_or_raise(
12501250
script_paths=build_options[_INSTALLATION_SUBDIR],
1251-
extra_packages=extra_packages,
1251+
packages=packages,
12521252
)
1253-
for extra_package in extra_packages:
1254-
if not os.path.exists(extra_package):
1255-
raise FileNotFoundError(
1256-
f"Extra package specified but not found: {extra_package=}"
1257-
)
1258-
return extra_packages
1253+
for package in packages:
1254+
if not os.path.exists(package):
1255+
raise FileNotFoundError(f"Package specified but not found: {package=}")
1256+
return packages
12591257

12601258

12611259
def _validate_installation_scripts_or_raise(
12621260
*,
12631261
script_paths: Sequence[str],
1264-
extra_packages: Sequence[str],
1262+
packages: Sequence[str],
12651263
) -> None:
12661264
"""Validates the installation scripts' path explicitly provided by the user.
12671265
12681266
Args:
12691267
script_paths (Sequence[str]):
12701268
Required. The paths to the installation scripts.
1271-
extra_packages (Sequence[str]):
1272-
Required. The extra packages to be updated.
1269+
packages (Sequence[str]):
1270+
Required. The user-provided packages.
12731271
12741272
Raises:
12751273
ValueError: If a user-defined script is not under the expected
1276-
subdirectory, or not in `extra_packages`, or if an extra package is
1274+
subdirectory, or not in `packages`, or if a package is
12771275
in the installation scripts subdirectory, but is not specified as an
12781276
installation script.
12791277
"""
@@ -1283,37 +1281,35 @@ def _validate_installation_scripts_or_raise(
12831281
f"User-defined installation script '{script_path}' is not in "
12841282
f"the expected '{_INSTALLATION_SUBDIR}' subdirectory. "
12851283
f"Ensure it is placed in '{_INSTALLATION_SUBDIR}' within your "
1286-
f"`extra_packages`."
1284+
f"'extra_packages' or 'source_packages'."
12871285
)
12881286
raise ValueError(
12891287
f"Required installation script '{script_path}' "
12901288
f"is not under '{_INSTALLATION_SUBDIR}'"
12911289
)
12921290

1293-
if script_path not in extra_packages:
1291+
if script_path not in packages:
12941292
logger.warning(
12951293
f"User-defined installation script '{script_path}' is not in "
1296-
f"extra_packages. Ensure it is added to `extra_packages`."
1294+
f"'extra_packages' or 'source_packages'. Ensure it is added to "
1295+
f"'extra_packages' or 'source_packages'."
12971296
)
12981297
raise ValueError(
12991298
f"User-defined installation script '{script_path}' "
1300-
f"does not exist in `extra_packages`"
1299+
f"does not exist in 'extra_packages' or 'source_packages'."
13011300
)
13021301

1303-
for extra_package in extra_packages:
1304-
if (
1305-
extra_package.startswith(_INSTALLATION_SUBDIR)
1306-
and extra_package not in script_paths
1307-
):
1302+
for package in packages:
1303+
if package.startswith(_INSTALLATION_SUBDIR) and package not in script_paths:
13081304
logger.warning(
1309-
f"Extra package '{extra_package}' is in the installation "
1305+
f"Package '{package}' is in the installation "
13101306
"scripts subdirectory, but is not specified as an installation "
13111307
"script in `build_options`. "
13121308
"Ensure it is added to installation_scripts for "
13131309
"automatic execution."
13141310
)
13151311
raise ValueError(
1316-
f"Extra package '{extra_package}' is in the installation "
1312+
f"Package '{package}' is in the installation "
13171313
"scripts subdirectory, but is not specified as an installation "
13181314
"script in `build_options`."
13191315
)

vertexai/_genai/agent_engines.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,8 +1067,8 @@ def _create_config(
10671067
agent=agent,
10681068
requirements=requirements,
10691069
)
1070-
extra_packages = _agent_engines_utils._validate_extra_packages_or_raise(
1071-
extra_packages=extra_packages,
1070+
extra_packages = _agent_engines_utils._validate_packages_or_raise(
1071+
packages=extra_packages,
10721072
build_options=build_options,
10731073
)
10741074
# Prepares the Agent Engine for creation/update in Vertex AI. This
@@ -1135,6 +1135,10 @@ def _create_config(
11351135
}
11361136

11371137
if source_packages is not None:
1138+
source_packages = _agent_engines_utils._validate_packages_or_raise(
1139+
packages=source_packages,
1140+
build_options=build_options,
1141+
)
11381142
update_masks.append("spec.source_code_spec.inline_source.source_archive")
11391143
source_code_spec = {
11401144
"inline_source": {

0 commit comments

Comments
 (0)