Skip to content

Commit 2212818

Browse files
authored
Graduate Common AI features to stable ahead of 1.0 (#74679)
Move @task.llm_sql, @task.llm_file_analysis, @task.llm_schema_compare, @task.llm_batch, ObjectStorageToolset, HookToolset.pinned_arguments and the framework-neutral tool interface into the stable table, and drop their "Experimental" notes. Every remaining experimental row now names a concrete reason: an outside dependency before its 1.0, a framework that changes often, or a change that is planned. Per-tool approval stays experimental because a task instance can pause for approval only once per Dag run. Two stated reasons were out of date: amazon and google implement the managed-agent contract, and CI runs the Strands and ADK adapter tests.
1 parent 142f12b commit 2212818

26 files changed

Lines changed: 105 additions & 141 deletions

‎providers/common/ai/docs/frameworks/adk.rst‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ it is, and add Airflow's toolsets to its tools with the
2828

2929
.. note::
3030

31-
``AirflowTools`` and the framework-neutral tool interface it builds on are
32-
experimental. They may change in a minor release of this provider.
31+
``AirflowTools`` is experimental: it may change in a minor release of this provider.
32+
The framework-neutral tool interface it builds on is stable.
3333
See :ref:`howto/stability`.
3434

3535
Run an ADK agent in a task

‎providers/common/ai/docs/frameworks/index.rst‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ is Airflow's and which part stays yours.
107107
- No agent
108108
- ``[llamaindex]`` extra
109109

110-
The Strands and ADK integrations, the framework-neutral tool interface under them, and
111-
the tracing helper are experimental: they can change or be removed in a minor release of
112-
this provider. See :ref:`howto/stability`.
110+
The Strands and ADK integrations and the tracing helper are experimental: they can change
111+
or be removed in a minor release of this provider. The framework-neutral tool interface
112+
under them is stable. See :ref:`howto/stability`.
113113

114114
Tested versions
115115
---------------

‎providers/common/ai/docs/frameworks/strands.rst‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ give it Airflow's toolsets with the
2929

3030
.. note::
3131

32-
``AirflowTools`` and the framework-neutral tool interface it builds on are
33-
experimental. They may change in a minor release of this provider.
32+
``AirflowTools`` is experimental: it may change in a minor release of this provider.
33+
The framework-neutral tool interface it builds on is stable.
3434
See :ref:`howto/stability`.
3535

3636
Run a Strands agent in a task

‎providers/common/ai/docs/operators/llm_batch.rst‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@
2020
Batch processing: ``LLMBatchOperator``
2121
======================================
2222

23-
.. note::
24-
25-
Experimental: this can change or be removed in a minor release of this provider.
26-
See :ref:`howto/stability`.
27-
2823
Use :class:`~airflow.providers.common.ai.operators.llm_batch.LLMBatchOperator` to run many
2924
prompts through a provider's **batch API** instead of one synchronous call per prompt:
3025
roughly half the per-token cost of :class:`~airflow.providers.common.ai.operators.llm.LLMOperator`,
@@ -315,6 +310,12 @@ storage with a reconciled manifest.
315310
Adding an adapter
316311
------------------
317312

313+
.. note::
314+
315+
Experimental: the adapter contract can change or be removed in a minor release of this
316+
provider.
317+
See :ref:`howto/stability`.
318+
318319
Another provider package can add a batch engine without changes here: subclass
319320
:class:`~airflow.providers.common.ai.batch.base.BatchAdapter`, set its ``name`` to the model
320321
prefix it serves and ``conn_types`` to the connection types it can authenticate from, and either

‎providers/common/ai/docs/operators/llm_file_analysis.rst‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@
2020
Analyze files and images: ``LLMFileAnalysisOperator`` and ``@task.llm_file_analysis``
2121
=====================================================================================
2222

23-
.. note::
24-
25-
Experimental: this can change or be removed in a minor release of this provider.
26-
See :ref:`howto/stability`.
27-
2823
Use :class:`~airflow.providers.common.ai.operators.llm_file_analysis.LLMFileAnalysisOperator`
2924
or the ``@task.llm_file_analysis`` decorator to analyze files from object storage
3025
or local storage with a single prompt.

‎providers/common/ai/docs/operators/llm_schema_compare.rst‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@
2020
Detect schema drift: ``LLMSchemaCompareOperator`` and ``@task.llm_schema_compare``
2121
==================================================================================
2222

23-
.. note::
24-
25-
Experimental: this can change or be removed in a minor release of this provider.
26-
See :ref:`howto/stability`.
27-
2823
Use :class:`~airflow.providers.common.ai.operators.llm_schema_compare.LLMSchemaCompareOperator`
2924
to compare schemas across different database systems and detect drift using LLM reasoning.
3025

‎providers/common/ai/docs/operators/llm_sql.rst‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@
2020
Natural language to SQL: ``LLMSQLQueryOperator`` and ``@task.llm_sql``
2121
======================================================================
2222

23-
.. note::
24-
25-
Experimental: this can change or be removed in a minor release of this provider.
26-
See :ref:`howto/stability`.
27-
2823
Use :class:`~airflow.providers.common.ai.operators.llm_sql.LLMSQLQueryOperator` to generate
2924
SQL queries from natural language using an LLM.
3025

‎providers/common/ai/docs/stability.rst‎

Lines changed: 84 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,44 @@ Pydantic AI toolsets, but the Pydantic AI class they inherit from can change.
6363
descriptions in ``branches``, as strings or as ``BranchOption(description=...)``,
6464
are sent to the model with the options. ``decision_policy`` and
6565
``BranchOption.min_confidence`` are experimental; see below.
66+
* - ``@task.llm_sql`` and
67+
:class:`~airflow.providers.common.ai.operators.llm_sql.LLMSQLQueryOperator`
68+
- Generates SQL from the prompt and returns it without running it. With
69+
``validate_sql=True``, the default, the task fails unless the output is a single
70+
statement that parses for ``dialect`` and is one of ``allowed_sql_types``
71+
(``SELECT``, ``UNION``, ``INTERSECT`` and ``EXCEPT`` by default); with the default
72+
types, a write nested inside the statement fails it too. A reviewer's edit under
73+
``allow_modifications=True`` is checked the same way. ``db_conn_id`` with
74+
``table_names``, ``schema_context`` or ``datasource_config`` give the model the
75+
schema.
76+
* - ``@task.llm_file_analysis`` and
77+
:class:`~airflow.providers.common.ai.operators.llm_file_analysis.LLMFileAnalysisOperator`
78+
- Reads the file at ``file_path``, or up to ``max_files`` files under a prefix,
79+
without changing them, and sends their content to the model with the prompt in one
80+
request: CSV, Parquet and Avro sampled to ``sample_rows`` rows, and all text cut to
81+
``max_text_chars``. Input over ``max_file_size_bytes`` or ``max_total_size_bytes``
82+
fails the task before the model is called, and so does an image or PDF unless
83+
``multi_modal=True``, which attaches it.
84+
* - ``@task.llm_schema_compare`` and
85+
:class:`~airflow.providers.common.ai.operators.llm_schema_compare.LLMSchemaCompareOperator`
86+
- Introspects the schemas of ``data_sources`` and of ``table_names`` on each of
87+
``db_conn_ids``, either or both, and returns a
88+
:class:`~airflow.providers.common.ai.operators.llm_schema_compare.SchemaCompareResult`
89+
as a dict: ``compatible``, ``summary`` and the ``mismatches``, each with a
90+
``severity`` of ``critical``, ``warning`` or ``info``. ``context_strategy="basic"``
91+
sends columns only; ``"full"``, the default, adds keys and indexes for database
92+
sources.
93+
* - ``@task.llm_batch`` and
94+
:class:`~airflow.providers.common.ai.operators.llm_batch.LLMBatchOperator`
95+
- Submits ``requests`` to the batch API that the ``model_id`` prefix selects, writes
96+
one JSONL row per request under ``result_path`` and returns the manifest
97+
(``schema_version: 1``) described in :doc:`operators/llm_batch`, never the results
98+
themselves. A retry or clear that renders the same ``result_path`` re-attaches to
99+
the batch already submitted while the requests, model, connection, system prompt,
100+
``max_tokens``, ``request_params`` and output schema are unchanged, unless that
101+
batch was cancelled or failed. On Airflow 3.3 and later, clearing a deferred task
102+
cancels its batch while ``cancel_on_kill=True``, the default. Adding a batch engine
103+
through ``BatchAdapter`` is experimental; see below.
66104
* - :class:`~airflow.providers.common.ai.hooks.pydantic_ai.PydanticAIHook` and its
67105
connection types
68106
- The connection fields documented for each type in :doc:`connections/pydantic_ai`,
@@ -80,13 +118,29 @@ Pydantic AI toolsets, but the Pydantic AI class they inherit from can change.
80118
- Exposes exactly the hook methods in ``allowed_methods``, each named
81119
``<tool_prefix>_<method>`` when ``tool_prefix`` is set, which must be a valid Python
82120
identifier, and raises an error when the toolset is created
83-
if a listed method does not exist on the hook. ``pinned_arguments`` is
84-
experimental; see below.
121+
if a listed method does not exist on the hook. Arguments in ``pinned_arguments``
122+
are left out of the schema the model sees and passed to every allowed method; a
123+
call that supplies one is refused, and the toolset raises an error when it is
124+
created if an allowed method does not take a pinned argument by that name.
125+
* - :class:`~airflow.providers.common.ai.toolsets.object_storage.ObjectStorageToolset`
126+
- Exposes ``list_files``, ``get_file_info`` and ``read_file`` for the files under the
127+
root path, read-only. Paths from the model are relative to the root: absolute
128+
paths, paths with a scheme and paths that climb out of the root are refused. A file
129+
the model cannot read, such as a binary file or one larger than ``max_read_bytes``,
130+
comes back to it as a message instead of failing the task.
85131
* - :class:`~airflow.providers.common.ai.toolsets.mcp.MCPToolset` and
86132
:class:`~airflow.providers.common.ai.hooks.mcp.MCPHook`
87133
- Exposes the tools of the MCP server configured by ``mcp_conn_id``, each named
88134
``<tool_prefix>_<name>`` when ``tool_prefix`` is set. The connection fields for each
89135
transport keep their meaning.
136+
* - The framework-neutral tool interface (:mod:`airflow.providers.common.ai.tools`):
137+
``AirflowTool``, ``ToolResult``, ``ToolCallError``, ``ToolProvider``,
138+
``collect_tools`` and the ``airflow_tools()`` method of the toolsets
139+
- An ``AirflowTool`` keeps its ``name``, ``description``, JSON Schema ``parameters``
140+
and async ``function``, and ``call()`` masks secrets in what it returns. A
141+
``ToolResult`` with ``is_error=True`` is a failure the model can correct;
142+
``ToolCallError`` fails the run. ``collect_tools`` raises ``ValueError`` when two
143+
tools share a name. An adapter for another agent framework can build on this.
90144
* - :class:`~airflow.providers.common.ai.policies.retry.LLMRetryPolicy`
91145
- Returns a retry decision from a model's reading of the exception. Values registered
92146
as secrets are masked in the exception text before it reaches the model, unless
@@ -113,48 +167,53 @@ Everything this provider ships that is not in the table above is experimental.
113167
- Why it is experimental
114168
* - :class:`~airflow.providers.common.ai.policies.retry.ClassifierRetryPolicy`
115169
(:doc:`decision_models`)
116-
- The confidence threshold, the fallback order and the behaviour when the classifier
117-
is unavailable are still settling.
170+
- What it does when the classifier is unsure or unavailable is changing.
118171
* - :class:`~airflow.providers.common.ai.policies.decision.DecisionPolicy`, and
119172
``min_confidence`` on
120173
:class:`~airflow.providers.common.ai.policies.decision.BranchOption`
121174
(:doc:`approval_gates`)
122-
- New. The threshold semantics and the recorded decision may change as they are
123-
used.
124-
* - ``@task.llm_batch`` and batch adapters (:doc:`operators/llm_batch`)
125-
- Submission, re-attachment on retry, cancellation and handling of partial results
126-
are still settling, and ``BatchAdapter`` has no implementation outside this
127-
provider yet.
175+
- Whether the confidence gate keeps this shape or becomes part of a wider decision
176+
policy is still open.
177+
* - Batch engines from other packages: ``BatchAdapter``, ``register_adapter()`` and the
178+
``airflow.providers.common.ai.batch_adapters`` entry point
179+
(:doc:`operators/llm_batch`)
180+
- No package outside this provider implements the contract yet, so it has not been
181+
tested by a second implementation.
128182
* - ``durable=True`` on ``AgentOperator`` (:doc:`durable_execution`)
129183
- Which tool results are replayed on retry will change, so that a tool can declare
130184
whether its result may be reused.
131185
* - Per-tool approval on ``AgentOperator`` (``tool_approval_timeout``,
132186
``on_tool_approval_timeout`` and ``tool_approval_assigned_users``;
133187
:doc:`tool_approval`)
134-
- New, and needs Airflow 3.3. How a paused run resumes may change.
135-
* - Code mode (:doc:`code_mode`), the Agent Skills toolset
136-
(:doc:`toolsets/skills`) and the ``shields`` extra (used in :doc:`capabilities`)
137-
- Thin integrations of packages outside this provider whose APIs are still
138-
changing: ``pydantic-ai-harness``, ``pydantic-ai-skills`` and
139-
``pydantic-ai-shields``.
188+
- A task instance can pause for approval only once per Dag run, so an agent that
189+
needs a second approval later in the run fails. Lifting that limit is planned.
190+
* - Code mode (:doc:`code_mode`) and the ``shields`` extra (used in
191+
:doc:`capabilities`)
192+
- Thin integrations of ``pydantic-ai-harness`` and ``pydantic-ai-shields``, which are
193+
before their 1.0 releases.
194+
* - The Agent Skills toolset (:doc:`toolsets/skills`)
195+
- It may move from ``pydantic-ai-skills`` to the on-demand loading Pydantic AI now has
196+
itself (`pydantic/pydantic-ai#5230 <https://github.com/pydantic/pydantic-ai/pull/5230>`__).
140197
* - :class:`~airflow.providers.common.ai.toolsets.sandbox.SandboxToolset` and its
141198
backends (:doc:`sandbox/index`)
142-
- The sandbox runtime belongs to the backend; ownership and cleanup across worker
143-
failures are still being designed.
199+
- ``durable=True`` cannot be used with it yet, the ``sbx`` backend leaves its sandbox
200+
behind when the worker is killed, and the backend contract is still gaining
201+
capabilities, such as attaching to a sandbox another task owns.
144202
* - LangChain and LlamaIndex hooks and the LangChain tool bridge
145203
(:doc:`hooks/langchain`, :doc:`toolsets/langchain`, :doc:`hooks/llamaindex`)
146204
- Each follows the API of a framework that changes often.
147205
* - The retrieval operators: ``DocumentLoaderOperator``,
148206
``LlamaIndexEmbeddingOperator`` and ``LlamaIndexRetrievalOperator``
149207
(:doc:`rag_pipelines`)
150-
- New. The shape of the pipeline, from loading documents through embedding to
151-
retrieval, has not settled.
208+
- Whether retrieval pipelines belong in this provider, which bridges Airflow to agent
209+
frameworks rather than replacing them, is still open.
152210
* - :class:`~airflow.providers.common.ai.toolsets.datafusion.DataFusionToolset`
153211
(:doc:`toolsets/datafusion`)
154212
- Runs on the DataFusion engine of ``common.sql``, which pins ``datafusion`` below 52
155213
and follows its API.
156214
* - Managed agent toolsets (:doc:`toolsets/managed_agent`)
157-
- A contract for vendor providers that no vendor implements yet.
215+
- The amazon and google providers implement the contract. The managed-agent operators
216+
of the other vendor providers are still being brought onto it, which can change it.
158217
* - OpenTelemetry spans (``[common.ai] otel_export_enabled`` and
159218
``capture_content``; :doc:`observability`)
160219
- Span names and attributes come from Pydantic AI's instrumentation and the
@@ -163,25 +222,10 @@ Everything this provider ships that is not in the table above is experimental.
163222
(:doc:`toolsets/logging`)
164223
- The wrapper ``AgentOperator`` applies for ``enable_tool_logging``; its constructor
165224
may change.
166-
* - ``@task.llm_schema_compare``, ``@task.llm_file_analysis`` and ``@task.llm_sql``
167-
(:doc:`operators/llm_schema_compare`, :doc:`operators/llm_file_analysis`,
168-
:doc:`operators/llm_sql`)
169-
- Each adds its own input handling to ``@task.llm``: schema introspection, file
170-
sampling, or SQL validation. Their options are still settling.
171-
* - The framework-neutral tools (:mod:`airflow.providers.common.ai.tools`), including
172-
the ``airflow_tools()`` method of the toolsets, the Strands plugin and the ADK
173-
toolset (:doc:`frameworks/index`)
174-
- Written against Strands 1.56 and ADK 2.9.1. CI does not run the tests of the two
175-
adapters, because both frameworks exclude dependency versions that Airflow's
176-
development environment uses.
177-
* - :class:`~airflow.providers.common.ai.toolsets.object_storage.ObjectStorageToolset`
178-
(:doc:`toolsets/object_storage`)
179-
- New; its tools and read limits may change after first use.
180-
* - ``pinned_arguments`` on
181-
:class:`~airflow.providers.common.ai.toolsets.hook.HookToolset`
182-
(:doc:`toolsets/hook`)
183-
- New; how a pinned argument is matched to each method's parameters may change after
184-
first use.
225+
* - The Strands plugin, the ADK toolset and Strands checkpoint resume
226+
(:doc:`frameworks/index`)
227+
- Written against Strands 1.56 and ADK 2.9.1, which change often. Strands marks its
228+
own checkpointing experimental.
185229
* - The ``common_ai.tool_calls`` metric and
186230
:func:`~airflow.providers.common.ai.tools.tracing.agent_framework_tracing`
187231
(:doc:`observability`)

‎providers/common/ai/docs/toolsets/hook.rst‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,6 @@ the ID from values the Dag controls, not from ``params`` or ``dag_run.conf`` (se
8585
Fix arguments the model must not choose
8686
---------------------------------------
8787

88-
.. note::
89-
90-
Experimental: ``pinned_arguments`` can change or be removed in a minor release of this
91-
provider.
92-
See :ref:`howto/stability`.
93-
9488
Exposing a method lets the model pick every argument it takes. When some of them are
9589
the Dag author's decision, such as which bucket a storage hook reads, pin them:
9690

‎providers/common/ai/docs/toolsets/object_storage.rst‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@
2020
Files on object storage: ``ObjectStorageToolset``
2121
=================================================
2222

23-
.. note::
24-
25-
Experimental: this can change or be removed in a minor release of this provider.
26-
See :ref:`howto/stability`.
27-
2823
Give an agent the files under one location in S3, GCS, Azure Blob Storage or any other
2924
store Airflow's :class:`~airflow.sdk.ObjectStoragePath` can open, and let it find and
3025
read what it needs: a month's reports, the config files of a failing job, the first

0 commit comments

Comments
 (0)