This is an automated email from the ASF dual-hosted git repository.

kaxil pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 16f974f6a35 Run the `common.ai` agent framework adapter tests in CI 
(#73912)
16f974f6a35 is described below

commit 16f974f6a35388c867bd1da1c2a3bf3d93e9c6cc
Author: Kaxil Naik <[email protected]>
AuthorDate: Wed Sep 30 18:52:06 2026 +0100

    Run the `common.ai` agent framework adapter tests in CI (#73912)
    
    * Run the common.ai agent framework adapter tests in CI
    
    Strands Agents caps mcp below the version uv.lock resolves, so it cannot
    be installed in the workspace and the common.ai adapter tests for it were
    skipped in every CI job.
    
    A new job installs the framework into the CI image and runs the tests of
    the framework-neutral tools and their adapters. Outside a canary run every
    package already in the image is held at its version with uv's --override,
    so the adapters are tested against the same dependencies as the rest of
    Airflow. On a canary run the framework's own pins win, which is what a user
    installing it gets. The job runs on main when common.ai or common.sql code,
    the common.ai dependencies or uv.lock change. It is not a dependency of
    finalize-tests, so a breaking framework release does not stop the image
    cache push, and notify-slack waits for it so a canary failure is reported.
    
    * Add Google ADK to the agent framework CI job
    
    ADK caps opentelemetry and websockets below the locked versions, the same 
way
    Strands caps mcp, so its adapter tests were skipped everywhere too. Both 
modes
    of the job install it now and check that it imports.
    
    * Run the agent framework tests one framework per job, on amd64 only
    
    Each matrix entry installs a single framework, so a breaking release of one
    cannot hide the other's result, and the entries run in parallel. The job is
    gated to amd64 inside the reusable workflow, since ci-amd.yml and ci-arm.yml
    must stay in sync.
    
    * Tighten the agent framework test script after review
    
    Drop the one-element framework array, fail with a message when the installed
    framework is missing from the freeze output instead of dying silently under
    pipefail, and document run-agent-framework-tests in the selective checks 
table.
---
 .github/workflows/agent-framework-tests.yml        | 89 +++++++++++++++++++++
 .github/workflows/ci-amd.yml                       | 19 +++++
 .github/workflows/ci-arm.yml                       | 19 +++++
 dev/breeze/doc/ci/04_selective_checks.md           |  1 +
 dev/breeze/doc/ci/05_workflows.md                  | 26 +++++++
 .../src/airflow_breeze/utils/selective_checks.py   | 18 +++++
 dev/breeze/tests/test_selective_checks.py          | 40 ++++++++++
 scripts/in_container/run_agent_framework_tests.sh  | 90 ++++++++++++++++++++++
 8 files changed, 302 insertions(+)

diff --git a/.github/workflows/agent-framework-tests.yml 
b/.github/workflows/agent-framework-tests.yml
new file mode 100644
index 00000000000..6e9de1174e9
--- /dev/null
+++ b/.github/workflows/agent-framework-tests.yml
@@ -0,0 +1,89 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+---
+name: Agent framework tests
+on:  # yamllint disable-line rule:truthy
+  workflow_call:
+    inputs:
+      runners:
+        description: "The array of labels (in json form) determining runners."
+        required: true
+        type: string
+      platform:
+        description: "Platform for the build - 'linux/amd64' or 'linux/arm64'"
+        required: true
+        type: string
+      default-python-version:
+        description: "Which version of python should be used by default"
+        required: true
+        type: string
+      use-uv:
+        description: "Whether to use uv"
+        required: true
+        type: string
+      canary-run:
+        description: >
+          On a canary run the frameworks' own dependency pins win, which is 
the environment a
+          user who installs them gets. Otherwise every package in the CI image 
keeps its version
+          and the frameworks' caps on them are overridden.
+        required: true
+        type: string
+permissions:
+  contents: read
+jobs:
+  tests:
+    timeout-minutes: 30
+    name: >-
+      Agent framework tests: ${{ matrix.framework }}
+      (${{ inputs.canary-run == 'true' && 'framework pins' || 'image versions' 
}})
+    runs-on: ${{ fromJSON(inputs.runners) }}
+    # amd64 only for now: ci-amd.yml and ci-arm.yml must stay in sync, so the 
platform gate lives here.
+    if: inputs.platform == 'linux/amd64'
+    strategy:
+      # One job per framework, so a breaking release of one does not hide the 
other's result.
+      fail-fast: false
+      matrix:
+        framework: [strands-agents, google-adk]
+    env:
+      GITHUB_REPOSITORY: ${{ github.repository }}
+      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      GITHUB_USERNAME: ${{ github.actor }}
+      PLATFORM: "${{ inputs.platform }}"
+      PYTHON_MAJOR_MINOR_VERSION: "${{ inputs.default-python-version }}"
+      VERBOSE: "true"
+      FRAMEWORK_PINS_FLAG: "${{ inputs.canary-run == 'true' && 
'--framework-pins' || '' }}"
+    steps:
+      - name: "Cleanup repo"
+        shell: bash
+        run: sudo rm -rf ${GITHUB_WORKSPACE}/*
+      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
+        uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1  # 
v7.0.1
+        with:
+          persist-credentials: false
+      - name: "Prepare breeze & CI image: ${{ inputs.default-python-version }}"
+        uses: ./.github/actions/prepare_breeze_and_image
+        with:
+          platform: ${{ inputs.platform }}
+          python: ${{ inputs.default-python-version }}
+          use-uv: ${{ inputs.use-uv }}
+          make-mnt-writeable-and-cleanup: true
+      - name: "Run the common.ai agent framework adapter tests"
+        run: >
+          breeze shell --backend none --skip-db-tests
+          "bash /opt/airflow/scripts/in_container/run_agent_framework_tests.sh
+          ${{ matrix.framework }} ${FRAMEWORK_PINS_FLAG}"
diff --git a/.github/workflows/ci-amd.yml b/.github/workflows/ci-amd.yml
index 7f3f761ac5e..8e670fbebd2 100644
--- a/.github/workflows/ci-amd.yml
+++ b/.github/workflows/ci-amd.yml
@@ -130,6 +130,7 @@ jobs:
       pull-request-labels: ${{ steps.source-run-info.outputs.pr-labels }}
       python-versions-list-as-string: ${{ 
steps.selective-checks.outputs.python-versions-list-as-string }}
       python-versions: ${{ steps.selective-checks.outputs.python-versions }}
+      run-agent-framework-tests: ${{ 
steps.selective-checks.outputs.run-agent-framework-tests }}
       run-airflow-ctl-tests: ${{ 
steps.selective-checks.outputs.run-airflow-ctl-tests }}
       run-airflow-ctl-integration-tests: ${{ 
steps.selective-checks.outputs.run-airflow-ctl-integration-tests }}
       run-amazon-tests: ${{ steps.selective-checks.outputs.run-amazon-tests }}
@@ -1138,6 +1139,23 @@ jobs:
       test-timeout: 20
     if: needs.build-info.outputs.run-airflow-ctl-tests == 'true'
 
+  tests-agent-frameworks:
+    name: "Agent framework tests"
+    uses: ./.github/workflows/agent-framework-tests.yml
+    needs: [build-info, build-ci-images]
+    permissions:
+      contents: read
+      packages: read
+    with:
+      runners: ${{ needs.build-info.outputs.runner-type }}
+      platform: ${{ needs.build-info.outputs.platform }}
+      default-python-version: "${{ 
needs.build-info.outputs.default-python-version }}"
+      use-uv: ${{ needs.build-info.outputs.use-uv }}
+      canary-run: ${{ needs.build-info.outputs.canary-run }}
+    # Not a dependency of finalize-tests: on a canary run the frameworks' own 
pins win, and a
+    # breaking framework release should not stop finalize-tests from pushing 
the image cache.
+    if: needs.build-info.outputs.run-agent-framework-tests == 'true'
+
   finalize-tests:
     name: Finalize tests
     permissions:
@@ -1197,6 +1215,7 @@ jobs:
     needs:
       - build-info
       - finalize-tests
+      - tests-agent-frameworks
     if: >-
       always() &&
       !cancelled() &&
diff --git a/.github/workflows/ci-arm.yml b/.github/workflows/ci-arm.yml
index 2f257f32c5a..88d7109c944 100644
--- a/.github/workflows/ci-arm.yml
+++ b/.github/workflows/ci-arm.yml
@@ -119,6 +119,7 @@ jobs:
       pull-request-labels: ${{ steps.source-run-info.outputs.pr-labels }}
       python-versions-list-as-string: ${{ 
steps.selective-checks.outputs.python-versions-list-as-string }}
       python-versions: ${{ steps.selective-checks.outputs.python-versions }}
+      run-agent-framework-tests: ${{ 
steps.selective-checks.outputs.run-agent-framework-tests }}
       run-airflow-ctl-tests: ${{ 
steps.selective-checks.outputs.run-airflow-ctl-tests }}
       run-airflow-ctl-integration-tests: ${{ 
steps.selective-checks.outputs.run-airflow-ctl-integration-tests }}
       run-amazon-tests: ${{ steps.selective-checks.outputs.run-amazon-tests }}
@@ -1127,6 +1128,23 @@ jobs:
       test-timeout: 20
     if: needs.build-info.outputs.run-airflow-ctl-tests == 'true'
 
+  tests-agent-frameworks:
+    name: "Agent framework tests"
+    uses: ./.github/workflows/agent-framework-tests.yml
+    needs: [build-info, build-ci-images]
+    permissions:
+      contents: read
+      packages: read
+    with:
+      runners: ${{ needs.build-info.outputs.runner-type }}
+      platform: ${{ needs.build-info.outputs.platform }}
+      default-python-version: "${{ 
needs.build-info.outputs.default-python-version }}"
+      use-uv: ${{ needs.build-info.outputs.use-uv }}
+      canary-run: ${{ needs.build-info.outputs.canary-run }}
+    # Not a dependency of finalize-tests: on a canary run the frameworks' own 
pins win, and a
+    # breaking framework release should not stop finalize-tests from pushing 
the image cache.
+    if: needs.build-info.outputs.run-agent-framework-tests == 'true'
+
   finalize-tests:
     name: Finalize tests
     permissions:
@@ -1186,6 +1204,7 @@ jobs:
     needs:
       - build-info
       - finalize-tests
+      - tests-agent-frameworks
     if: >-
       always() &&
       !cancelled() &&
diff --git a/dev/breeze/doc/ci/04_selective_checks.md 
b/dev/breeze/doc/ci/04_selective_checks.md
index 489d60a8f73..d413de863a6 100644
--- a/dev/breeze/doc/ci/04_selective_checks.md
+++ b/dev/breeze/doc/ci/04_selective_checks.md
@@ -599,6 +599,7 @@ GitHub Actions to pass the list of parameters to a command 
to execute
 | pyproject-toml-changed                                  | When 
pyproject.toml changed in the PR.                                               
                   | false                                    |      |
 | python-versions                                         | List of python 
versions to use for that build                                                  
         | \['3.10'\]                               |      |
 | python-versions-list-as-string                          | Which versions of 
MySQL to use for tests as space-separated string                                
      | 3.10                                     | *    |
+| run-agent-framework-tests                               | Whether the 
common.ai agent framework adapter tests should be run ("true"/"false")          
            | true                                     |      |
 | run-amazon-tests                                        | Whether Amazon 
tests should be run ("true"/"false")                                            
         | true                                     |      |
 | run-api-codegen                                         | Whether 
"api-codegen" are needed to run ("true"/"false")                                
                | true                                     |      |
 | run-api-tests                                           | Whether 
"api-tests" are needed to run ("true"/"false")                                  
                | true                                     |      |
diff --git a/dev/breeze/doc/ci/05_workflows.md 
b/dev/breeze/doc/ci/05_workflows.md
index 5d1f51c87eb..e62dc41a283 100644
--- a/dev/breeze/doc/ci/05_workflows.md
+++ b/dev/breeze/doc/ci/05_workflows.md
@@ -262,6 +262,7 @@ Here's what each workflow group does and when it runs:
 | **Additional PROD Image Tests**    | Final validation of production images 
(AMD only)            | Yes     | Yes     | Yes       |
 | **Kubernetes Tests**               | Tests deployment in Kubernetes 
environments                 | Yes     | Yes     | Yes (1)   |
 | **Distribution Tests**             | Tests Task SDK and CLI tools (AMD only) 
                    | Yes     | Yes     | Yes       |
+| **Agent Framework Tests**          | Tests Common AI's adapters for other 
agent frameworks (4)   | Yes     | Yes     | No        |
 | **Finalize Tests**                 | Publishes results and updates shared 
resources              | Yes     | Yes (2) | Yes (2)   |
 
 #### AMD-Only Workflows
@@ -312,6 +313,31 @@ Special tests (integration and system tests) run 
selectively:
 - In canary runs for scheduled quality checks
 - When dependency upgrades require thorough testing
 
+**`(4)` Agent Framework Tests**
+
+The [Common AI provider](../../../../providers/common/ai/docs/index.rst) lets 
an agent built with
+another framework use Airflow's toolsets, through small adapters in
+[`airflow.providers.common.ai.tools`](../../../../providers/common/ai/src/airflow/providers/common/ai/tools).
+The adapter tests import the framework they adapt, so they only run where that 
framework is
+installed. Today that is two frameworks, [Strands 
Agents](https://strandsagents.com/), an open-source
+agent SDK from AWS, and [Google ADK](https://google.github.io/adk-docs/), and 
neither can be installed
+in the workspace: Strands caps `mcp`, and ADK caps `opentelemetry` and 
`websockets`, below the versions
+`uv.lock` resolves. The regular test jobs therefore skip their adapter tests.
+
+This job runs once per framework, each installing its framework into the CI 
image and running the
+Common AI tool tests (`providers/common/ai/tests/unit/common/ai/tools`), so a 
breaking release of one
+framework does not hide the other's result. It runs on `main` only, on amd64, 
when Common AI or
+common.sql code, the Common AI dependencies or `uv.lock` change, or when the 
run tests everything.
+
+- Outside a canary run, every package in the image keeps its version and the 
frameworks' caps on them
+  are overridden, so the adapters are tested against the same dependencies as 
the rest of Airflow.
+- On a canary run, the frameworks' own dependency pins win, which is the 
environment a user who
+  installs them gets.
+
+Both install the newest framework releases older than the repository's uv 
`exclude-newer` window, so a
+release that breaks an adapter fails this job about that long after it ships. 
The job is not a
+dependency of **Finalize Tests**, so such a release does not stop the image 
cache from being pushed.
+
 ## Runners
 
 Two kinds of GitHub-hosted runner are used, and which one a job gets depends 
on what
diff --git a/dev/breeze/src/airflow_breeze/utils/selective_checks.py 
b/dev/breeze/src/airflow_breeze/utils/selective_checks.py
index f278d044bc7..68dfad6edf7 100644
--- a/dev/breeze/src/airflow_breeze/utils/selective_checks.py
+++ b/dev/breeze/src/airflow_breeze/utils/selective_checks.py
@@ -122,6 +122,7 @@ class FileGroupForCi(Enum):
     KUBERNETES_FILES = auto()
     TASK_SDK_FILES = auto()
     TASK_SDK_INTEGRATION_TEST_FILES = auto()
+    AGENT_FRAMEWORK_FILES = auto()
     GO_SDK_FILES = auto()
     JAVA_SDK_FILES = auto()
     TS_SDK_FILES = auto()
@@ -482,6 +483,16 @@ CI_FILE_GROUP_MATCHES: HashableDict[FileGroupForCi] = 
HashableDict(
         FileGroupForCi.TASK_SDK_INTEGRATION_TEST_FILES: [
             r"^task-sdk-integration-tests/.*\.py$",
         ],
+        FileGroupForCi.AGENT_FRAMEWORK_FILES: [
+            # The framework adapters sit on the framework-neutral tools, which 
sit on the toolsets,
+            # so any code change in the provider can break them, and so can a 
change to common.sql,
+            # which the SQL toolset uses, or to the locked versions the job 
holds the framework to.
+            # The job's own script and workflow are ENVIRONMENT_FILES, which 
run everything.
+            r"^providers/common/ai/(src|tests)/.*\.py$",
+            r"^providers/common/ai/pyproject\.toml$",
+            r"^providers/common/sql/src/.*\.py$",
+            r"^uv\.lock$",
+        ],
         FileGroupForCi.GO_SDK_FILES: [
             # `.md` excluded — doc-only edits do not affect the Go build or 
tests, but
             # everything else (go.mod, go.sum, build config) must trigger the 
unit tests.
@@ -1145,6 +1156,13 @@ class SelectiveChecks:
             FileGroupForCi.TASK_SDK_INTEGRATION_TEST_FILES
         )
 
+    @cached_property
+    def run_agent_framework_tests(self) -> bool:
+        # Providers are released from main only, as for skip_providers_tests.
+        if self._default_branch != "main":
+            return False
+        return self._should_be_run(FileGroupForCi.AGENT_FRAMEWORK_FILES)
+
     @cached_property
     def run_go_sdk_tests(self) -> bool:
         return self._should_be_run(FileGroupForCi.GO_SDK_FILES)
diff --git a/dev/breeze/tests/test_selective_checks.py 
b/dev/breeze/tests/test_selective_checks.py
index f496912f6b3..533cd41a6a8 100644
--- a/dev/breeze/tests/test_selective_checks.py
+++ b/dev/breeze/tests/test_selective_checks.py
@@ -1598,6 +1598,41 @@ def assert_outputs_are_printed(expected_outputs: 
dict[str, str], stderr: str):
             },
             id="Skip go unit and e2e tests for go-sdk ADR-only change",
         ),
+        pytest.param(
+            
("providers/common/ai/src/airflow/providers/common/ai/toolsets/sql.py",),
+            {"run-agent-framework-tests": "true", "full-tests-needed": 
"false"},
+            id="Run agent framework tests when a common.ai toolset changes",
+        ),
+        pytest.param(
+            
("providers/common/ai/tests/unit/common/ai/tools/test_strands.py",),
+            {"run-agent-framework-tests": "true", "full-tests-needed": 
"false"},
+            id="Run agent framework tests when a common.ai test changes",
+        ),
+        pytest.param(
+            ("providers/common/ai/pyproject.toml",),
+            {"run-agent-framework-tests": "true", "full-tests-needed": 
"false"},
+            id="Run agent framework tests when common.ai dependencies change",
+        ),
+        pytest.param(
+            
("providers/common/sql/src/airflow/providers/common/sql/hooks/sql.py",),
+            {"run-agent-framework-tests": "true", "full-tests-needed": 
"false"},
+            id="Run agent framework tests when common.sql changes",
+        ),
+        pytest.param(
+            ("uv.lock",),
+            {"run-agent-framework-tests": "true", "full-tests-needed": 
"false"},
+            id="Run agent framework tests when the lock file changes",
+        ),
+        pytest.param(
+            ("providers/common/ai/docs/frameworks/strands.rst",),
+            {"run-agent-framework-tests": "false"},
+            id="Skip agent framework tests for a common.ai docs-only change",
+        ),
+        pytest.param(
+            ("providers/openai/src/airflow/providers/openai/hooks/openai.py",),
+            {"run-agent-framework-tests": "false"},
+            id="Skip agent framework tests when another provider changes",
+        ),
         pytest.param(
             ("airflow-e2e-tests/docker/go.yml",),
             {
@@ -2544,6 +2579,11 @@ def test_expected_output_full_tests_needed(
             id="No Helm tests, No providers no lint charts, should run if "
             "only chart/providers changed in non-main but PROD image should be 
built",
         ),
+        pytest.param(
+            
("providers/common/ai/src/airflow/providers/common/ai/toolsets/sql.py",),
+            {"run-agent-framework-tests": "false", "skip-providers-tests": 
"true"},
+            id="No agent framework tests on a release branch, which releases 
no providers",
+        ),
         pytest.param(
             (
                 "airflow-core/src/airflow/cli/test.py",
diff --git a/scripts/in_container/run_agent_framework_tests.sh 
b/scripts/in_container/run_agent_framework_tests.sh
new file mode 100755
index 00000000000..2053c68fdc1
--- /dev/null
+++ b/scripts/in_container/run_agent_framework_tests.sh
@@ -0,0 +1,90 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Runs the common.ai adapter tests for agent frameworks that cannot join the 
workspace lock.
+#
+# Strands Agents caps mcp, and Google ADK caps opentelemetry and websockets, 
below the versions
+# uv.lock resolves, so their adapter tests are skipped everywhere else in CI. 
This installs one
+# framework into the CI image and runs the tests of the framework-neutral 
tools and their adapters;
+# the other framework's tests skip themselves. One framework per invocation, 
so a bad release of
+# one cannot mask the other.
+#
+# By default every package already in the image is held at its installed 
version with uv's
+# --override, so the framework is tested against the same dependencies as the 
rest of Airflow and
+# its caps on them are overridden. With --framework-pins the framework's own 
requirements win
+# instead, which is the environment a user who installs it gets.
+#
+# The newest framework release older than the repository's uv exclude-newer 
window is installed.
+set -euo pipefail
+
+TEST_PATH="providers/common/ai/tests/unit/common/ai/tools"
+
+framework="${1:-}"
+case "${framework}" in
+    strands-agents) import_check="import strands" ;;
+    google-adk) import_check="import google.adk" ;;
+    *)
+        echo "Usage: $0 <strands-agents|google-adk> [--framework-pins]" >&2
+        exit 1
+        ;;
+esac
+
+framework_pins="false"
+if [[ ${2:-} == "--framework-pins" ]]; then
+    framework_pins="true"
+elif [[ -n ${2:-} ]]; then
+    echo "Unknown argument: ${2}. The only option after the framework is 
--framework-pins." >&2
+    exit 1
+fi
+
+cd "${AIRFLOW_SOURCES:-/opt/airflow}"
+
+if [[ ${framework_pins} == "true" ]]; then
+    echo "Installing ${framework} with its own dependency pins"
+    uv pip install "${framework}"
+else
+    overrides=$(mktemp)
+    before=$(mktemp)
+    after=$(mktemp)
+    trap 'rm -f "${overrides}" "${before}" "${after}"' EXIT
+    uv pip freeze | sort > "${before}"
+    # Only name==version lines: editable and local installs cannot be 
expressed as an override,
+    # and the frameworks do not depend on any of them. Overriding the rest 
means nothing the
+    # image ships should change; the check below is there in case something 
still does.
+    grep -E '^[A-Za-z0-9_.-]+==' "${before}" > "${overrides}"
+    echo "Installing ${framework}, holding the image's $(wc -l < 
"${overrides}") installed packages"
+    uv pip install --override "${overrides}" "${framework}"
+    uv pip freeze | sort > "${after}"
+    changed=$(comm -23 "${before}" "${after}")
+    if [[ -n ${changed} ]]; then
+        echo "Installing ${framework} changed packages the image already had:" 
>&2
+        echo "${changed}" >&2
+        exit 1
+    fi
+fi
+
+# Log the versions that decide whether the adapter works; the framework itself 
must be among them.
+uv pip freeze | grep -iE 
'^(strands-agents|google-adk|mcp|opentelemetry-(api|sdk)|websockets|google-genai)=='
 \
+    || { echo "${framework} is not installed after uv pip install" >&2; exit 
1; }
+
+# The adapter tests skip themselves when their framework is missing, so a 
broken install would
+# otherwise pass as green.
+python -c "${import_check}"
+
+# --skip-db-tests: the job runs with backend "none", which has no database to 
set up.
+pytest "${TEST_PATH}" --skip-db-tests -p no:cacheprovider --color=yes -ra

Reply via email to