Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ description = "Standalone framework to evaluate agent correctness based on porta
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"google-adk[eval]>=2.1.0,<2.2",
"click>=8.0",
# Cap: ADK ships breaking changes in minor releases (e.g. 2.2, 2.5, 2.7), so <3 is not a safe guardrail.
"google-adk[eval]>=2.5.0,<2.8",
"click>=8.3.3",
"tabulate>=0.9.0",
"fastapi>=0.115.0",
"uvicorn[standard]>=0.32.0",
Expand All @@ -28,6 +29,7 @@ dependencies = [
"litellm>=1.85.7",
"nltk>=3.10.2",
"pyasn1>=0.6.4",
"pygments>=2.20.0",
"requests>=2.34.2",
"urllib3>=2.7.0",
]
Expand Down Expand Up @@ -83,7 +85,7 @@ asyncio_mode = "auto"

[dependency-groups]
dev = [
"pytest>=9.0.2",
"pytest>=9.0.3",
"pytest-asyncio>=0.24.0",
"httpx>=0.27.0",
"ruff>=0.11.0",
Expand Down
31 changes: 27 additions & 4 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,27 @@
from agentevals.runner import RunResult


def _route_paths(app) -> set[str]:
"""Collect every mounted route path, descending into lazily-included routers.

FastAPI >=0.133 keeps each ``include_router`` call as a single ``_IncludedRouter``
wrapper in ``app.routes`` rather than flattening its routes into the list, so a
plain ``route.path`` sweep both misses those paths and raises on the wrapper.
"""
paths: set[str] = set()
stack: list[tuple[str, object]] = [("", route) for route in app.routes]
while stack:
prefix, route = stack.pop()
path = getattr(route, "path", None)
if path is not None:
paths.add(prefix + path)
included = getattr(route, "original_router", None)
if included is not None:
nested = prefix + getattr(route.include_context, "prefix", "")
stack.extend((nested, inner) for inner in included.routes)
return paths


class _FakeGrpcServer:
def __init__(self):
self.started = False
Expand Down Expand Up @@ -84,10 +105,12 @@ def fake_server_factory(config):
assert fake_grpc_server.started is True
assert created_servers[0].handle_exit is not None
assert created_servers[1].handle_exit is not None
assert any(route.path == "/ws/traces" for route in main_app.routes)
assert any(route.path == "/stream/ui-updates" for route in main_app.routes)
assert any(route.path == "/v1/traces" for route in otlp_app.routes)
assert any(route.path == "/v1/logs" for route in otlp_app.routes)
main_paths = _route_paths(main_app)
otlp_paths = _route_paths(otlp_app)
assert "/ws/traces" in main_paths
assert "/stream/ui-updates" in main_paths
assert "/v1/traces" in otlp_paths
assert "/v1/logs" in otlp_paths
fake_stop_grpc.assert_awaited_once_with(fake_grpc_server)


Expand Down
Loading
Loading