diff --git a/pyproject.toml b/pyproject.toml index 67824f41f8..a2bfc8cf1c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -192,7 +192,7 @@ optional-dependencies.e2b = [ ] optional-dependencies.eval = [ "gepa>=0.1", - "google-cloud-aiplatform[evaluation]>=1.148", + "google-cloud-aiplatform[evaluation]>=1.148,<2", "google-cloud-texttospeech>=2.37", "jinja2>=3.1.4,<4", # For eval template rendering "nltk!=3.10.1", # Transitive via rouge-score; 3.10.1's import hook breaks any venv living inside the working directory (reverted upstream in nltk/nltk#3732). diff --git a/tests/unittests/test_release_dependencies.py b/tests/unittests/test_release_dependencies.py index 513a3ed4d6..e41b4b9685 100644 --- a/tests/unittests/test_release_dependencies.py +++ b/tests/unittests/test_release_dependencies.py @@ -28,9 +28,11 @@ * ``google-genai`` MUST exclude 2.11 and floor at 2.12.1 or later, since that release is the first whose types module defers the optional MCP server stack instead of importing it at Agent startup. -* The ``all`` extra MUST stay the union of every extra that unlocks a runtime - feature, so that ``pip install "google-adk[all]"`` cannot silently stop - installing a feature's dependencies. +* ``all`` MUST stay the union of every extra that unlocks a runtime feature, so + that ``pip install "google-adk[all]"`` cannot silently stop installing a + feature's dependencies. +* The ``eval`` extra MUST keep ``google-cloud-aiplatform`` below its 2.x major + line, matching the other runtime extras that depend on it. * Every ``<=`` upper bound MUST name the release the tests run against, so that raising one cannot claim support for a release nothing installed. """ @@ -331,6 +333,27 @@ def test_main_deps_require_lazy_mcp_google_genai_release( ) +def test_eval_extra_caps_google_cloud_aiplatform_at_v2( + pyproject: dict, +) -> None: + """The eval extra must not resolve google-cloud-aiplatform 2.x.""" + specifier = _requirement_specifier( + pyproject['project']['optional-dependencies']['eval'], + 'google-cloud-aiplatform', + ) + + assert specifier is not None, ( + 'The eval extra must declare google-cloud-aiplatform so its evaluation ' + 'dependency remains explicitly constrained.' + ) + assert any( + clause.operator == '<' and Version(clause.version) == Version('2') + for clause in specifier + ), 'The eval extra must keep google-cloud-aiplatform below the 2.x major line.' + assert Version('1.148') in specifier + assert Version('2.0.0') not in specifier + + def test_inclusive_upper_bounds_ignores_other_operators() -> None: """Only ``<=`` names a release as supported, and the highest one wins.""" bounds = _inclusive_upper_bounds({