diff --git a/.github/.release-please-manifest.json b/.github/.release-please-manifest.json index 215f02e088..48dc31349e 100644 --- a/.github/.release-please-manifest.json +++ b/.github/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.27.4" + ".": "1.27.5" } diff --git a/CHANGELOG.md b/CHANGELOG.md index b0423f8073..348886d8d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## [1.27.5](https://github.com/google/adk-python/compare/v1.27.4...v1.27.5) (2026-03-26) +### Bug Fixes + +* Update eval extras to Vertex SDK package version with constrained LiteLLM upperbound ([77928a8](https://github.com/google/adk-python/commit/77928a81c39a955c2559b80d3ce137d6503b5264)) + ## [1.27.4](https://github.com/google/adk-python/compare/v1.27.3...v1.27.4) (2026-03-24) ### Bug Fixes diff --git a/src/google/adk/cli/fast_api.py b/src/google/adk/cli/fast_api.py index 0b6f3fb6fe..4d666f78d3 100644 --- a/src/google/adk/cli/fast_api.py +++ b/src/google/adk/cli/fast_api.py @@ -291,7 +291,7 @@ def _normalize_relative_path(path: str) -> str: def _has_parent_reference(path: str) -> bool: return any(part == ".." for part in path.split("/")) - _ALLOWED_EXTENSIONS = frozenset({".yaml", ".yml"}) + _ALLOWED_UPLOAD_EXTENSIONS = frozenset({".yaml", ".yml"}) def _parse_upload_filename(filename: Optional[str]) -> tuple[str, str]: if not filename: @@ -307,10 +307,10 @@ def _parse_upload_filename(filename: Optional[str]) -> tuple[str, str]: if _has_parent_reference(rel_path): raise ValueError(f"Path traversal rejected: {filename!r}") ext = os.path.splitext(rel_path)[1].lower() - if ext not in _ALLOWED_EXTENSIONS: + if ext not in _ALLOWED_UPLOAD_EXTENSIONS: raise ValueError( f"File type not allowed: {rel_path!r}" - f" (allowed: {', '.join(sorted(_ALLOWED_EXTENSIONS))})" + f" (allowed: {', '.join(sorted(_ALLOWED_UPLOAD_EXTENSIONS))})" ) return app_name, rel_path @@ -322,12 +322,6 @@ def _parse_file_path(file_path: str) -> str: raise ValueError(f"Absolute file_path rejected: {file_path!r}") if _has_parent_reference(file_path): raise ValueError(f"Path traversal rejected: {file_path!r}") - ext = os.path.splitext(file_path)[1].lower() - if ext not in _ALLOWED_EXTENSIONS: - raise ValueError( - f"File type not allowed: {file_path!r}" - f" (allowed: {', '.join(sorted(_ALLOWED_EXTENSIONS))})" - ) return file_path def _resolve_under_dir(root_dir: Path, rel_path: str) -> Path: diff --git a/src/google/adk/version.py b/src/google/adk/version.py index 552556e23b..d83daa73f1 100644 --- a/src/google/adk/version.py +++ b/src/google/adk/version.py @@ -13,4 +13,4 @@ # limitations under the License. # version: major.minor.patch -__version__ = "1.27.4" +__version__ = "1.27.5" diff --git a/tests/unittests/cli/test_fast_api.py b/tests/unittests/cli/test_fast_api.py index 15bc908ddb..e53d5a918c 100755 --- a/tests/unittests/cli/test_fast_api.py +++ b/tests/unittests/cli/test_fast_api.py @@ -1759,40 +1759,6 @@ def test_builder_save_allows_yaml_files(builder_test_client, tmp_path): assert response.json() is True -def test_builder_get_rejects_non_yaml_file_paths(builder_test_client, tmp_path): - """GET /builder/app/{app_name}?file_path=... rejects non-YAML extensions.""" - app_root = tmp_path / "app" - app_root.mkdir(parents=True, exist_ok=True) - (app_root / ".env").write_text("SECRET=supersecret\n") - (app_root / "agent.py").write_text("root_agent = None\n") - (app_root / "config.json").write_text("{}\n") - - for file_path in [".env", "agent.py", "config.json"]: - response = builder_test_client.get( - f"/builder/app/app?file_path={file_path}" - ) - assert response.status_code == 200, f"Expected 200 for {file_path}" - assert response.text == "", f"Expected empty response for {file_path}" - - -def test_builder_get_allows_yaml_file_paths(builder_test_client, tmp_path): - """GET /builder/app/{app_name}?file_path=... allows YAML extensions.""" - app_root = tmp_path / "app" - app_root.mkdir(parents=True, exist_ok=True) - (app_root / "sub_agent.yaml").write_text("name: sub\n") - (app_root / "tool.yml").write_text("name: tool\n") - - response = builder_test_client.get( - "/builder/app/app?file_path=sub_agent.yaml" - ) - assert response.status_code == 200 - assert response.text == "name: sub\n" - - response = builder_test_client.get("/builder/app/app?file_path=tool.yml") - assert response.status_code == 200 - assert response.text == "name: tool\n" - - def test_builder_endpoints_not_registered_without_web( mock_session_service, mock_artifact_service,