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 2002ba522e6 Graduate durable agent execution to stable in Common AI 
(#74704)
2002ba522e6 is described below

commit 2002ba522e69c122ccd06d145e38cc3559cdaae2
Author: Kaxil Naik <[email protected]>
AuthorDate: Wed Oct 14 09:50:09 2026 +0100

    Graduate durable agent execution to stable in Common AI (#74704)
    
    AirflowDurability (#74385) let a toolset declare whether its calls may be
    replayed, which was the reason durable=True stayed experimental in #74679.
---
 providers/common/ai/docs/durable_execution.rst       |  5 -----
 providers/common/ai/docs/stability.rst               | 20 +++++++++++++++-----
 providers/common/ai/docs/why_common_ai.rst           |  7 +++----
 .../airflow/providers/common/ai/operators/agent.py   |  2 +-
 4 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/providers/common/ai/docs/durable_execution.rst 
b/providers/common/ai/docs/durable_execution.rst
index 10555ab20e1..59d4aaa7408 100644
--- a/providers/common/ai/docs/durable_execution.rst
+++ b/providers/common/ai/docs/durable_execution.rst
@@ -20,11 +20,6 @@
 Durable execution
 =================
 
-.. note::
-
-    Experimental: this can change or be removed in a minor release of this 
provider.
-    See :ref:`howto/stability`.
-
 An agent task makes several model calls and tool calls. When it fails partway 
(a
 network error, a timeout, a provider outage), a plain Airflow retry runs every 
one of
 them again: the model calls are paid for twice and the tools' side effects 
happen
diff --git a/providers/common/ai/docs/stability.rst 
b/providers/common/ai/docs/stability.rst
index 278377648fa..abf65413ff2 100644
--- a/providers/common/ai/docs/stability.rst
+++ b/providers/common/ai/docs/stability.rst
@@ -50,8 +50,8 @@ Pydantic AI toolsets, but the Pydantic AI class they inherit 
from can change.
        always dumped to a dict. ``decision_policy`` is experimental; see below.
    * - ``@task.agent`` and 
:class:`~airflow.providers.common.ai.operators.agent.AgentOperator`
      - Runs an agent with the model from ``llm_conn_id`` and the given 
toolsets, and
-       returns its output under the same rules as ``@task.llm``. ``durable`` 
and
-       code mode are experimental; see below.
+       returns its output under the same rules as ``@task.llm``. Code mode is
+       experimental; see below.
    * - Per-tool approval on ``AgentOperator`` (:doc:`tool_approval`)
      - On Airflow 3.3 and later, a call to a tool marked with Pydantic AI's 
approval API
        (``approval_required(...)`` on a toolset, or ``requires_approval=True`` 
on a
@@ -69,6 +69,19 @@ Pydantic AI toolsets, but the Pydantic AI class they inherit 
from can change.
      - Seeds the run with the given conversation, as a list of messages or its 
JSON form,
        and publishes the finished conversation under the ``message_history`` 
XCom key so a
        later run can continue it. Cannot be combined with 
``enable_hitl_review``.
+   * - ``durable=True`` on ``AgentOperator`` and ``@task.agent``, and
+       :class:`~airflow.providers.common.ai.durable.AirflowDurability`
+       (:doc:`durable_execution`)
+     - On a retry the agent runs from the start, and each model request and 
tool call an
+       earlier attempt recorded is replayed from the journal kept for the task 
instance,
+       without calling the model or running the tool again, as long as it 
matches the step
+       recorded at the same point; from the first step that differs, every 
step runs live.
+       The journal is kept in the task state store on Airflow 3.3 and later, 
and under
+       ``[common.ai] durable_cache_path`` before. With ``durable=True``, 
replayed steps
+       count nothing against ``usage_limits`` or in the ``usage`` XCom, the 
agent's
+       ``run_id`` stays the first attempt's, and the journal is deleted when 
the task
+       succeeds. In a plain ``@task``, ``AirflowDurability`` deletes a run's 
steps when
+       that run succeeds.
    * - ``@task.llm_branch`` and
        
:class:`~airflow.providers.common.ai.operators.llm_branch.LLMBranchOperator`
      - The model picks among the task's direct downstream tasks, one by 
default or several
@@ -192,9 +205,6 @@ Everything this provider ships that is not in the table 
above is experimental.
        (:doc:`operators/llm_batch`)
      - No package outside this provider implements the contract yet, so it has 
not been
        tested by a second implementation.
-   * - ``durable=True`` on ``AgentOperator`` (:doc:`durable_execution`)
-     - Which tool results are replayed on retry will change, so that a tool 
can declare
-       whether its result may be reused.
    * - Code mode (:doc:`code_mode`) and the ``shields`` extra (used in
        :doc:`capabilities`)
      - Thin integrations of ``pydantic-ai-harness`` and 
``pydantic-ai-shields``, which are
diff --git a/providers/common/ai/docs/why_common_ai.rst 
b/providers/common/ai/docs/why_common_ai.rst
index 447d3da00fe..992b54945fd 100644
--- a/providers/common/ai/docs/why_common_ai.rst
+++ b/providers/common/ai/docs/why_common_ai.rst
@@ -93,9 +93,8 @@ and a bucket of report files. What differs:
   environment. ``AgentOperator`` takes both from a connection, so moving to 
another vendor
   or adding a fallback is a connection change. See :doc:`model_providers`.
 - **A retry.** The plain task starts again from the beginning and pays for 
every call
-  again. ``durable=True`` replays the calls that finished and continues from 
there. It is
-  experimental, and before Airflow 3.3 it needs ``[common.ai] 
durable_cache_path`` set; see
-  :doc:`durable_execution`.
+  again. ``durable=True`` replays the calls that finished and continues from 
there. Before
+  Airflow 3.3 it needs ``[common.ai] durable_cache_path`` set; see 
:doc:`durable_execution`.
 - **Spend.** In the plain task, Pydantic AI's default limit of 50 model 
requests applies
   to each attempt on its own, so three attempts can make up to 150. With 
``usage_limits``
   on Airflow 3.3 and later, one total covers all three attempts, and the task 
fails once
@@ -120,7 +119,7 @@ What a plain task leaves to you
     * - The task retries after the agent has already made model and tool calls.
       - ``durable=True`` on ``AgentOperator`` replays the calls that finished 
and runs
         the rest live. If the prompt, model or tools changed since the failed 
attempt,
-        the affected calls run again. Experimental.
+        the affected calls run again.
       - :doc:`durable_execution`
     * - A run must not spend past a limit, retries included.
       - ``usage_limits`` counts every attempt of the task instance together on
diff --git 
a/providers/common/ai/src/airflow/providers/common/ai/operators/agent.py 
b/providers/common/ai/src/airflow/providers/common/ai/operators/agent.py
index 6215733d224..9078c2e9f85 100644
--- a/providers/common/ai/src/airflow/providers/common/ai/operators/agent.py
+++ b/providers/common/ai/src/airflow/providers/common/ai/operators/agent.py
@@ -341,7 +341,7 @@ class AgentOperator(CancellableAgentRunMixin, BaseOperator, 
HITLReviewMixin, Usa
         :ref:`the cross-attempt usage budget <agent-usage-budget>` for how
         it is persisted, reset, and how ``durable`` replay and HITL
         regeneration interact with it.
-    :param durable: Experimental. When ``True``, attaches
+    :param durable: When ``True``, attaches
         :class:`~airflow.providers.common.ai.durable.AirflowDurability`, which
         records each step the agent completes -- model responses, tool calls 
from
         any toolset or capability, tool discovery, and other capabilities'

Reply via email to