Skip to content
Merged
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
38 changes: 26 additions & 12 deletions py/noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,24 @@ def _get_matrix_versions(prefix: str) -> tuple[str, ...]:
return tuple(latest + rest)


def _install_matrix_dep(session: nox.Session, prefix: str, version: str) -> None:
"""Install the matrix dep for a provider at a specific version."""
def _install_matrix_dep(session: nox.Session, prefix: str, version: str, constraint_group: str | None = None) -> None:
"""Install a matrix dependency, optionally using pinned compatibility constraints."""
matrix_entry = _MATRIX.get(prefix, {})
key = "latest" if version == LATEST else version
req = matrix_entry.get(key)
if req:
if not req:
return
if constraint_group is None:
session.install(req, silent=SILENT_INSTALLS)
return

constraints = _PYPROJECT.get("dependency-groups", {}).get(constraint_group, [])
if not constraints or not all(isinstance(constraint, str) for constraint in constraints):
session.error(f"Constraint group {constraint_group!r} must contain only requirement strings")
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt") as constraint_file:
constraint_file.write("\n".join(constraints))
constraint_file.flush()
session.install(req, "-c", constraint_file.name, silent=SILENT_INSTALLS)


# ---------------------------------------------------------------------------
Expand Down Expand Up @@ -334,7 +345,9 @@ def test_litellm(session, version):
@nox.parametrize("version", CLAUDE_AGENT_SDK_VERSIONS, ids=CLAUDE_AGENT_SDK_VERSIONS)
def test_claude_agent_sdk(session, version):
_install_test_deps(session)
_install_matrix_dep(session, "claude-agent-sdk", version)
# Claude Agent SDK 0.1.10 calls Server.list_tools(), which MCP 2 removed.
constraint_group = "test-mcp-v1" if version == "0.1.10" else None
_install_matrix_dep(session, "claude-agent-sdk", version, constraint_group)
_run_tests(session, f"{INTEGRATION_DIR}/claude_agent_sdk/test_claude_agent_sdk.py", version=version)


Expand Down Expand Up @@ -393,7 +406,9 @@ def test_agentscope(session, version):
if version == LATEST and sys.version_info < (3, 11):
session.skip("AgentScope 2.x requires Python 3.11+")
_install_test_deps(session)
_install_matrix_dep(session, "agentscope", version)
# AgentScope 1.0.0 imports streamablehttp_client, which MCP 2 no longer exports.
constraint_group = "test-mcp-v1" if version == "1.0.0" else None
_install_matrix_dep(session, "agentscope", version, constraint_group)
_install_group_locked(session, "test-agentscope")
_run_tests(session, f"{INTEGRATION_DIR}/agentscope/test_agentscope.py", version=version)

Expand Down Expand Up @@ -421,7 +436,9 @@ def test_autogen(session, version):
@nox.parametrize("version", PYDANTIC_AI_INTEGRATION_VERSIONS, ids=PYDANTIC_AI_INTEGRATION_VERSIONS)
def test_pydantic_ai_integration(session, version):
_install_test_deps(session)
_install_matrix_dep(session, "pydantic-ai-integration", version)
# Pydantic AI 1.10.0 imports opentelemetry._events, removed in opentelemetry-api 1.40.
constraint_group = "test-pydantic-ai-otel-events" if version == "1.10.0" else None
_install_matrix_dep(session, "pydantic-ai-integration", version, constraint_group)
_run_tests(session, f"{INTEGRATION_DIR}/pydantic_ai/test_pydantic_ai_integration.py", version=version)


Expand All @@ -440,12 +457,9 @@ def test_pydantic_ai_logfire(session, version):
def test_pydantic_ai_wrap_openai(session, version):
"""Test pydantic_ai with wrap_openai() approach - supports older versions."""
_install_test_deps(session)
_install_matrix_dep(session, "pydantic-ai-wrap-openai", version)
# pydantic-ai 0.1.9 unconditionally imports ``from opentelemetry._events import Event``.
# The ``_events`` module was removed from ``opentelemetry-api`` in 1.40+, so a fresh
# resolution on newer opentelemetry releases picks a version that breaks import.
if version == "0.1.9":
session.install("opentelemetry-api<1.40", silent=SILENT_INSTALLS)
# These versions import opentelemetry._events, removed in opentelemetry-api 1.40.
constraint_group = "test-pydantic-ai-otel-events" if version in {"0.1.9", "1.0.1"} else None
_install_matrix_dep(session, "pydantic-ai-wrap-openai", version, constraint_group)
_run_tests(session, f"{INTEGRATION_DIR}/pydantic_ai/test_pydantic_ai_wrap_openai.py", version=version)


Expand Down
15 changes: 15 additions & 0 deletions py/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,17 @@ test-agentscope = [
"openai==2.31.0",
]

# Compatibility constraints for older provider versions. These groups are
# used as pip constraint files, so they do not install optional packages that
# the provider itself does not require.
test-mcp-v1 = [
"mcp==1.28.1",
]

test-pydantic-ai-otel-events = [
"opentelemetry-api==1.39.1",
]

test-strands = [
{include-group = "test"},
"openai==2.32.0",
Expand Down Expand Up @@ -301,6 +312,10 @@ conflicts = [
{group = "test-pydantic-ai-logfire"},
{group = "test-livekit-agents"},
],
[
{group = "test-pydantic-ai-otel-events"},
{group = "test-livekit-agents"},
],
]

# ---------------------------------------------------------------------------
Expand Down
Loading