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 03c71e50eb2 Bump common.ai floor to pydantic-ai-slim>=1.71.0 and 
document capabilities passthrough (#67444)
03c71e50eb2 is described below

commit 03c71e50eb23cbb501e79da7848d7a83347a237c
Author: Kaxil Naik <[email protected]>
AuthorDate: Sat May 30 01:48:11 2026 +0100

    Bump common.ai floor to pydantic-ai-slim>=1.71.0 and document capabilities 
passthrough (#67444)
    
    1.71.0 is the first release that ships the `pydantic_ai.capabilities`
    module (Thinking, WebSearch, ImageGeneration, MCP, etc.). Bumping the
    floor lets users pass capabilities through `AgentOperator(agent_params=...)`
    without operator-level support landing first.
    
    The new example DAG demonstrates the pattern with Thinking, WebSearch,
    and composition with SQLToolset. The agent.rst guide adds a short
    "Capabilities (pydantic-ai)" section with a warning about the templated-
    field serialization gap -- first-class `capabilities=` support is left
    as a follow-up.
    
    Generated metadata (README.rst, docs/index.rst, uv.lock) updated to match.
---
 docs/spelling_wordlist.txt                         |   1 +
 providers/common/ai/README.rst                     |   2 +-
 providers/common/ai/docs/index.rst                 |   2 +-
 providers/common/ai/docs/operators/agent.rst       |  40 +++++++-
 providers/common/ai/pyproject.toml                 |   2 +-
 .../ai/example_dags/example_agent_capabilities.py  | 114 +++++++++++++++++++++
 uv.lock                                            |   2 +-
 7 files changed, 158 insertions(+), 5 deletions(-)

diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index 222d69aab8a..fe93cebe41a 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -275,6 +275,7 @@ ColumnLineageDatasetFacet
 CommandType
 comparator
 compat
+composable
 Compute
 compute
 ComputeManagementClient
diff --git a/providers/common/ai/README.rst b/providers/common/ai/README.rst
index f9a587ec140..e4e21058ddb 100644
--- a/providers/common/ai/README.rst
+++ b/providers/common/ai/README.rst
@@ -56,7 +56,7 @@ PIP package                                 Version required
 ``apache-airflow``                          ``>=3.0.0``
 ``apache-airflow-providers-common-compat``  ``>=1.14.1``
 ``apache-airflow-providers-standard``       ``>=1.12.1``
-``pydantic-ai-slim``                        ``>=1.34.0``
+``pydantic-ai-slim``                        ``>=1.71.0``
 ==========================================  ==================
 
 Cross provider package dependencies
diff --git a/providers/common/ai/docs/index.rst 
b/providers/common/ai/docs/index.rst
index 05e35ea22c8..adde6dbe9cc 100644
--- a/providers/common/ai/docs/index.rst
+++ b/providers/common/ai/docs/index.rst
@@ -108,7 +108,7 @@ PIP package                                 Version required
 ``apache-airflow``                          ``>=3.0.0``
 ``apache-airflow-providers-common-compat``  ``>=1.14.1``
 ``apache-airflow-providers-standard``       ``>=1.12.1``
-``pydantic-ai-slim``                        ``>=1.34.0``
+``pydantic-ai-slim``                        ``>=1.71.0``
 ==========================================  ==================
 
 Cross provider package dependencies
diff --git a/providers/common/ai/docs/operators/agent.rst 
b/providers/common/ai/docs/operators/agent.rst
index 9f66b5aea3c..f1c13fb4490 100644
--- a/providers/common/ai/docs/operators/agent.rst
+++ b/providers/common/ai/docs/operators/agent.rst
@@ -255,6 +255,42 @@ skipped with a warning and will re-execute on retry 
instead of replaying from
 cache. The task itself still succeeds.
 
 
+.. _capabilities-passthrough:
+
+Capabilities (pydantic-ai)
+--------------------------
+
+pydantic-ai `capabilities <https://ai.pydantic.dev/capabilities/>`__ bundle
+tools, lifecycle hooks, instructions, and model settings into composable units.
+Common ones include ``Thinking`` (reasoning at a configurable effort level),
+``WebSearch``, ``WebFetch``, ``ImageGeneration``, and ``MCP``.
+
+``AgentOperator`` does not yet expose a first-class ``capabilities=`` kwarg,
+but anything passed through ``agent_params`` is forwarded to the underlying
+``Agent(...)`` constructor.
+
+.. exampleinclude:: 
/../../ai/src/airflow/providers/common/ai/example_dags/example_agent_capabilities.py
+    :language: python
+    :start-after: [START howto_operator_agent_capabilities_thinking]
+    :end-before: [END howto_operator_agent_capabilities_thinking]
+
+Capabilities compose with toolsets -- pydantic-ai merges tools from both.
+
+.. exampleinclude:: 
/../../ai/src/airflow/providers/common/ai/example_dags/example_agent_capabilities.py
+    :language: python
+    :start-after: [START howto_operator_agent_capabilities_composed]
+    :end-before: [END howto_operator_agent_capabilities_composed]
+
+.. warning::
+
+    ``agent_params`` is a templated field, which Airflow serializes by calling
+    ``str()`` on values it doesn't natively understand. Capability instances
+    are not yet round-trip-safe through DAG serialization, so the examples
+    below construct them inside the ``@dag`` function -- not at module level.
+    First-class ``capabilities=`` support on ``AgentOperator`` (with proper
+    serializer hooks) is tracked as a follow-up.
+
+
 Parameters
 ----------
 
@@ -273,7 +309,9 @@ Parameters
   :class:`~airflow.providers.common.ai.toolsets.logging.LoggingToolset` so that
   every tool call is logged in real time. Default ``True``.
 - ``agent_params``: Additional keyword arguments passed to the pydantic-ai
-  ``Agent`` constructor (e.g. ``retries``, ``model_settings``).
+  ``Agent`` constructor (e.g. ``retries``, ``model_settings``, 
``capabilities``).
+  See :ref:`capabilities-passthrough` for how to enable pydantic-ai 
capabilities
+  such as ``Thinking``, ``WebSearch``, and ``ImageGeneration``.
 - ``usage_limits``: Optional pydantic-ai ``UsageLimits`` enforced on every
   agent run (initial run, durable replay, and HITL regeneration). Use it to
   cap requests, tokens, or tool calls per task -- agents are particularly
diff --git a/providers/common/ai/pyproject.toml 
b/providers/common/ai/pyproject.toml
index 8a0e6bacbe1..0f684c26941 100644
--- a/providers/common/ai/pyproject.toml
+++ b/providers/common/ai/pyproject.toml
@@ -69,7 +69,7 @@ dependencies = [
     "apache-airflow>=3.0.0",
     "apache-airflow-providers-common-compat>=1.14.1",
     "apache-airflow-providers-standard>=1.12.1",
-    "pydantic-ai-slim>=1.34.0",
+    "pydantic-ai-slim>=1.71.0",
 ]
 
 # The optional dependencies should be modified in place in the generated file
diff --git 
a/providers/common/ai/src/airflow/providers/common/ai/example_dags/example_agent_capabilities.py
 
b/providers/common/ai/src/airflow/providers/common/ai/example_dags/example_agent_capabilities.py
new file mode 100644
index 00000000000..3d069acdf33
--- /dev/null
+++ 
b/providers/common/ai/src/airflow/providers/common/ai/example_dags/example_agent_capabilities.py
@@ -0,0 +1,114 @@
+# 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.
+"""Example DAGs demonstrating pydantic-ai capabilities via ``agent_params``.
+
+Capabilities (https://ai.pydantic.dev/capabilities/) are pydantic-ai's
+composable units for thinking, web search, image generation, MCP, and more.
+``AgentOperator`` forwards anything in ``agent_params`` to the underlying
+``Agent(...)`` constructor, so capabilities work today without operator-level
+support. A first-class ``capabilities=`` kwarg is on the roadmap.
+"""
+
+from __future__ import annotations
+
+from pydantic_ai.capabilities import Thinking, WebSearch
+
+from airflow.providers.common.ai.operators.agent import AgentOperator
+from airflow.providers.common.ai.toolsets.sql import SQLToolset
+from airflow.providers.common.compat.sdk import dag
+
+# ---------------------------------------------------------------------------
+# 1. Thinking capability: enable model reasoning at a configurable effort level
+# ---------------------------------------------------------------------------
+
+
+# [START howto_operator_agent_capabilities_thinking]
+@dag(tags=["example"])
+def example_agent_capabilities_thinking():
+    AgentOperator(
+        task_id="reasoner",
+        prompt="Walk through the steps to compute the 10th Fibonacci number, 
then give the answer.",
+        llm_conn_id="pydanticai_default",
+        system_prompt="You are a careful mathematician. Think before 
answering.",
+        agent_params={
+            "capabilities": [Thinking(effort="high")],
+        },
+    )
+
+
+# [END howto_operator_agent_capabilities_thinking]
+
+example_agent_capabilities_thinking()
+
+
+# ---------------------------------------------------------------------------
+# 2. WebSearch capability: provider-adaptive web search as a single declaration
+# ---------------------------------------------------------------------------
+
+
+# [START howto_operator_agent_capabilities_web_search]
+@dag(tags=["example"])
+def example_agent_capabilities_web_search():
+    AgentOperator(
+        task_id="researcher",
+        prompt="Summarize the latest Apache Airflow 3.x release notes from 
airflow.apache.org.",
+        llm_conn_id="pydanticai_default",
+        system_prompt="You are a release-notes summarizer. Cite the source 
URL.",
+        agent_params={
+            "capabilities": [WebSearch()],
+        },
+    )
+
+
+# [END howto_operator_agent_capabilities_web_search]
+
+example_agent_capabilities_web_search()
+
+
+# ---------------------------------------------------------------------------
+# 3. Composing capabilities with toolsets
+# ---------------------------------------------------------------------------
+# Capabilities and toolsets compose: pydantic-ai merges tools from both.
+
+
+# [START howto_operator_agent_capabilities_composed]
+@dag(tags=["example"])
+def example_agent_capabilities_composed():
+    AgentOperator(
+        task_id="analyst",
+        prompt="Cross-reference our top customers with their recent public 
news. Think first.",
+        llm_conn_id="pydanticai_default",
+        system_prompt=(
+            "You are a sales analyst. Query the database for customers, then 
search the web "
+            "for recent news. Reason carefully about which leads to surface."
+        ),
+        toolsets=[
+            SQLToolset(
+                db_conn_id="postgres_default",
+                allowed_tables=["customers", "orders"],
+                max_rows=20,
+            ),
+        ],
+        agent_params={
+            "capabilities": [Thinking(effort="medium"), WebSearch()],
+        },
+    )
+
+
+# [END howto_operator_agent_capabilities_composed]
+
+example_agent_capabilities_composed()
diff --git a/uv.lock b/uv.lock
index caf92c6b934..d80641fe5ca 100644
--- a/uv.lock
+++ b/uv.lock
@@ -4326,7 +4326,7 @@ requires-dist = [
     { name = "llama-index-llms-openai", marker = "extra == 'llamaindex'", 
specifier = ">=0.6.0" },
     { name = "pyarrow", marker = "python_full_version >= '3.14' and extra == 
'parquet'", specifier = ">=22.0.0" },
     { name = "pyarrow", marker = "python_full_version < '3.14' and extra == 
'parquet'", specifier = ">=18.0.0" },
-    { name = "pydantic-ai-slim", specifier = ">=1.34.0" },
+    { name = "pydantic-ai-slim", specifier = ">=1.71.0" },
     { name = "pydantic-ai-slim", extras = ["anthropic"], marker = "extra == 
'anthropic'" },
     { name = "pydantic-ai-slim", extras = ["bedrock"], marker = "extra == 
'bedrock'" },
     { name = "pydantic-ai-slim", extras = ["google"], marker = "extra == 
'google'" },

Reply via email to