kaxil commented on code in PR #72155:
URL: https://github.com/apache/airflow/pull/72155#discussion_r4004604077


##########
providers/common/ai/src/airflow/providers/common/ai/operators/llm.py:
##########
@@ -135,8 +143,21 @@ def __init__(
         self._serialize_model_output = serialize_output or not _CORE_WALKER
         self.agent_params = agent_params or {}
         self.usage_limits = usage_limits
+        if on_approval_timeout not in ("fail", 
*LLMApprovalMixin.TIMEOUT_DEFAULTS):
+            raise ValueError(
+                f"on_approval_timeout must be 'fail', 'approve', or 'reject', 
got {on_approval_timeout!r}."
+            )
+        if on_approval_timeout != "fail" and not (
+            require_approval and approval_timeout is not None and 
approval_timeout > timedelta(0)
+        ):
+            raise ValueError(
+                f"on_approval_timeout={on_approval_timeout!r} has no effect 
without "

Review Comment:
   "has no effect" is not quite right now that the same commit documents a 
second effect. With `require_approval=True` and no `approval_timeout`, 
`defer_for_approval` still passes `defaults=timeout_defaults` to the upsert 
(`mixins/approval.py:174`), so the review form pre-highlights the chosen option 
exactly as the new docs sentence describes; only the deadline never fires. 
Rejecting that combination is a defensible call, since the parameter is named 
for a timeout, but the message tells the user the setting does nothing when it 
would in fact change what the reviewer sees. Naming the missing piece instead, 
along the lines of "needs a positive `approval_timeout` to fire", matches what 
the check requires.



##########
providers/common/ai/src/airflow/providers/common/ai/mixins/approval.py:
##########
@@ -179,16 +190,22 @@ def defer_for_approval(
             trigger=HITLTrigger(
                 ti_id=ti_id,
                 options=[LLMApprovalMixin.APPROVE, LLMApprovalMixin.REJECT],
-                defaults=None,
+                defaults=timeout_defaults,
                 params=hitl_params,
                 multiple=False,
                 timeout_datetime=utcnow() + self.approval_timeout if 
self.approval_timeout else None,

Review Comment:
   Correcting my own round-3 claim first: I said the pre-3.3 `timedelta(0)` 
behaviour pre-dated the PR, and it did not. I read the branch after the 
`timeout=` removal had already landed rather than `main`.
   
   At the merge base `self.defer()` still carried 
`timeout=self.approval_timeout`, and nothing on that path tests the value for 
truthiness. Checked against the released `3.2.2` tag, which is the core this 
PR's own compat job runs: `TaskDeferred` stores the value as passed, 
`task-sdk/.../task_runner.py:1211` forwards it as `trigger_timeout`, and the 
execution API gates on `is not None` 
(`execution_api/routes/task_instances.py:549-550`). So `timedelta(0)` landed 
`TI.trigger_timeout = utcnow()`, and `check_trigger_timeouts` 
(`scheduler_job_runner.py:2915-2916`) flipped the TI to `__fail__` on the next 
tick.
   
   Dropping that kwarg, which I asked for, leaves this line as the only 
authority, and `bool(timedelta(0))` is `False`. `approval_timeout=timedelta(0)` 
now yields `timeout_datetime=None`, so `HITLTrigger.run()` pokes every 5s 
forever where it used to fail. 3.3+ is unaffected, since `TaskAwaitingInput` 
reaches the same `is not None` test (`3.3.0` tag: the awaiting-input branch at 
`task_instances.py:709` applies it at `:739`).
   
   The new `__init__` guard does not cover this, because it only fires when 
`on_approval_timeout != "fail"` -- so the configuration that hangs is the 
default one. `if self.approval_timeout is not None else None` restores the old 
outcome and makes the two wait paths agree: a deadline of `utcnow()` sends the 
first `run()` iteration into `_handle_timeout`, which with `defaults=None` 
yields the timeout failure event.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to