Skip to content

Commit 6960ae4

Browse files
shawn-yang-googlecopybara-github
authored andcommitted
feat: Add pydantic to default required packages for agent engines
PiperOrigin-RevId: 749861402
1 parent 7b955e9 commit 6960ae4

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed

tests/unit/vertex_langchain/test_agent_engines.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,11 @@ def register_operations(self) -> Dict[str, List[str]]:
399399
_TEST_STREAM_QUERY_SCHEMAS = [
400400
_TEST_AGENT_ENGINE_STREAM_QUERY_SCHEMA,
401401
]
402+
_TEST_PACKAGE_DISTRIBUTIONS = {
403+
"requests": ["requests"],
404+
"cloudpickle": ["cloudpickle"],
405+
"pydantic": ["pydantic"],
406+
}
402407

403408

404409
def _create_empty_fake_package(package_name: str) -> str:
@@ -507,6 +512,16 @@ def importlib_metadata_version_mock():
507512
with mock.patch.object(
508513
importlib.metadata, "version"
509514
) as importlib_metadata_version_mock:
515+
516+
def get_version(pkg):
517+
versions = {
518+
"requests": "2.0.0",
519+
"cloudpickle": "3.0.0",
520+
"pydantic": "1.11.1",
521+
}
522+
return versions.get(pkg, "unknown")
523+
524+
importlib_metadata_version_mock.side_effect = get_version
510525
yield importlib_metadata_version_mock
511526

512527

@@ -616,6 +631,14 @@ def unregister_api_methods_mock():
616631
yield unregister_api_methods_mock
617632

618633

634+
def create_fake_object_with_module(module_name):
635+
class FakeObject:
636+
pass
637+
638+
FakeObject.__module__ = module_name
639+
return FakeObject()
640+
641+
619642
class InvalidCapitalizeEngineWithoutQuerySelf:
620643
"""A sample Agent Engine with an invalid query method."""
621644

@@ -2519,3 +2542,69 @@ def test_compare_requirements_with_required_packages(self):
25192542
"missing": set(),
25202543
},
25212544
}
2545+
2546+
@pytest.mark.usefixtures("importlib_metadata_version_mock")
2547+
def test_scan_simple_object(self):
2548+
"""Test scanning an object importing a known third-party package."""
2549+
fake_obj = create_fake_object_with_module("requests")
2550+
requirements = _utils.scan_requirements(
2551+
fake_obj,
2552+
package_distributions=_TEST_PACKAGE_DISTRIBUTIONS,
2553+
)
2554+
assert requirements == {
2555+
"cloudpickle": "3.0.0",
2556+
"pydantic": "1.11.1",
2557+
"requests": "2.0.0",
2558+
}
2559+
2560+
@pytest.mark.usefixtures("importlib_metadata_version_mock")
2561+
def test_scan_object_with_stdlib_module(self):
2562+
"""Test that stdlib modules are ignored by default."""
2563+
fake_obj_stdlib = create_fake_object_with_module("json")
2564+
requirements = _utils.scan_requirements(
2565+
fake_obj_stdlib,
2566+
package_distributions=_TEST_PACKAGE_DISTRIBUTIONS,
2567+
)
2568+
# Requirements should not contain 'json',
2569+
# because 'json' is a stdlib module.
2570+
assert requirements == {
2571+
"cloudpickle": "3.0.0",
2572+
"pydantic": "1.11.1",
2573+
}
2574+
2575+
@pytest.mark.usefixtures("importlib_metadata_version_mock")
2576+
def test_scan_with_default_ignore_modules(self, monkeypatch):
2577+
"""Test implicitly ignoring a module."""
2578+
fake_obj = create_fake_object_with_module("requests")
2579+
original_base = _utils._BASE_MODULES
2580+
monkeypatch.setattr(
2581+
_utils,
2582+
"_BASE_MODULES",
2583+
set(original_base) | {"requests"},
2584+
)
2585+
requirements = _utils.scan_requirements(
2586+
fake_obj,
2587+
package_distributions=_TEST_PACKAGE_DISTRIBUTIONS,
2588+
)
2589+
# Requirements should not contain 'requests',
2590+
# because 'requests' is implicitly ignored in `_BASE_MODULES`.
2591+
assert requirements == {
2592+
"cloudpickle": "3.0.0",
2593+
"pydantic": "1.11.1",
2594+
}
2595+
2596+
@pytest.mark.usefixtures("importlib_metadata_version_mock")
2597+
def test_scan_with_explicit_ignore_modules(self):
2598+
"""Test explicitly ignoring a module."""
2599+
fake_obj = create_fake_object_with_module("requests")
2600+
requirements = _utils.scan_requirements(
2601+
fake_obj,
2602+
ignore_modules=["requests"],
2603+
package_distributions=_TEST_PACKAGE_DISTRIBUTIONS,
2604+
)
2605+
# Requirements should not contain 'requests',
2606+
# because 'requests' is explicitly ignored in `ignore_modules`.
2607+
assert requirements == {
2608+
"cloudpickle": "3.0.0",
2609+
"pydantic": "1.11.1",
2610+
}

vertexai/agent_engines/_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class _RequirementsValidationResult(TypedDict):
110110
LOGGER = base.Logger("vertexai.agent_engines")
111111

112112
_BASE_MODULES = set(_BUILTIN_MODULE_NAMES + tuple(_STDLIB_MODULE_NAMES))
113-
_DEFAULT_REQUIRED_PACKAGES = frozenset(["cloudpickle"])
113+
_DEFAULT_REQUIRED_PACKAGES = frozenset(["cloudpickle", "pydantic"])
114114
_ACTIONS_KEY = "actions"
115115
_ACTION_APPEND = "append"
116116
_WARNINGS_KEY = "warnings"

0 commit comments

Comments
 (0)