Skip to content

Bound LLM operator usage_limits across task retries - #74396

Merged
Lee-W merged 5 commits into
apache:mainfrom
astronomer:llm-operator-usage-budget-across-retries
Oct 11, 2026
Merged

Lee-W merged 5 commits into
apache:mainfrom
astronomer:llm-operator-usage-budget-across-retries

Conversation

@Lee-W

@Lee-W Lee-W commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

On Airflow 3.3+, AgentOperator already carries its spend across retries through the task state store, but LLMOperator and its subclasses counted usage_limits per attempt, so every retry got a fresh budget and a failing LLM task could spend retries x the configured limit. Applying the same cumulative budget to the LLM operators closes that gap, and sharing one implementation keeps the two operator families from drifting apart.


Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: [Claude] following the guidelines


  • Read the Pull Request Guidelines for more information. Note: commit author/co-author name and email in commits become permanently public when merged.
  • For fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
  • When adding dependency, check compliance with the ASF 3rd Party License Policy.
  • For significant user-facing changes create newsfragment: {pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.

@Lee-W
Lee-W marked this pull request as ready for review October 7, 2026 08:13
@Lee-W
Lee-W force-pushed the llm-operator-usage-budget-across-retries branch 6 times, most recently from 93a7380 to 78c0754 Compare October 9, 2026 07:39
Comment thread providers/common/ai/src/airflow/providers/common/ai/mixins/usage_budget.py Outdated
Comment thread providers/common/ai/docs/changelog.rst Outdated
Comment thread providers/common/ai/docs/operators/llm.rst
Comment thread providers/common/ai/tests/unit/common/ai/mixins/test_usage_budget.py Outdated
Comment thread providers/common/ai/tests/unit/common/ai/conftest.py
Lee-W added 4 commits October 11, 2026 07:57
On Airflow 3.3+, AgentOperator already carries its spend across retries
through the task state store, but LLMOperator and its subclasses counted
usage_limits per attempt, so every retry got a fresh budget and a failing
LLM task could spend retries x the configured limit. Applying the same
cumulative budget to the LLM operators closes that gap, and sharing one
implementation keeps the two operator families from drifting apart.
Clearing the persisted usage after a resumed review no longer coerces usage_limits or reads the task instance, so a usage_limits template that no longer renders to a valid value cannot fail a task the reviewer already approved.

Remove UsageBudgetMixin._get_usage_budget; LLMOperator reads the task instance itself only when usage_limits is set.
The LLM* operators now count usage_limits across the whole task
instance on Airflow 3.3+, but llm.rst still said that applied to
AgentOperator only. Update the request and token limit bullets, note that
clearing a running task instance keeps the old spend, and add an
unreleased changelog note for the LLM* operators. The 0.11.0 AgentOperator
note is restored to what shipped in providers-common-ai/0.11.0rc1.

Also state in the LLMOperator docstring that nothing may fail the attempt
once the usage budget is cleared, since a retry would start with a fresh
budget. Subclasses that override execute or execute_complete are affected.
The build-budget test only checked the budget's type, so a wrong task
state store or a wrong max_tries (which would reset the budget on every
retry) went unnoticed. It now saves through the budget and asserts the
record lands in the context's accessor with max_tries == 3.

test_agent.py had its own copy of the task_state_store_accessor fixture
from conftest.py; use the shared fixture and drop the copy.
@Lee-W
Lee-W force-pushed the llm-operator-usage-budget-across-retries branch from 78c0754 to 62a6a7a Compare October 11, 2026 06:57
The test saves through the budget, and save() imports NEVER_EXPIRE, which
only exists on Airflow 3.3+. Older versions swallow the ImportError, so
nothing reaches the store and the test fails there.
@Lee-W
Lee-W merged commit ed572af into apache:main Oct 11, 2026
85 checks passed
@Lee-W
Lee-W deleted the llm-operator-usage-budget-across-retries branch October 11, 2026 09:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants