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


##########
providers/common/ai/src/airflow/providers/common/ai/mixins/hitl_review.py:
##########
@@ -181,8 +185,12 @@ def _poll_loop(
                     key=XCOM_HUMAN_ACTION, task_ids=ti.task_id, 
map_indexes=ti.map_index
                 )
             except Exception:
+                consecutive_pull_failures += 1
+                if consecutive_pull_failures >= 
_MAX_CONSECUTIVE_XCOM_PULL_FAILURES:
+                    raise

Review Comment:
   Failures 1 to 9 log a warning, but the 10th re-raises with nothing saying 
why, so the task log ends with a raw `xcom_pull` exception that looks like a 
one-off error. Since nobody is watching when this fires, a line like 
`self.log.error("Giving up HITL review after %d consecutive XCom pull 
failures", consecutive_pull_failures)` before the `raise` would tell on-call it 
was the HITL loop giving up.



##########
providers/common/ai/src/airflow/providers/common/ai/operators/llm.py:
##########
@@ -197,7 +198,7 @@ def __init__(
         model_id: str | None = None,
         fallback_conn_ids: list[str] | None = None,
         system_prompt: str = "",
-        output_type: type = str,
+        output_type: OutputSpec[Any] = str,

Review Comment:
   `OutputSpec` also admits `[A, B]` and marker forms like `ToolOutput(A)`, and 
the description says list forms are accepted now. Those break the approval 
resume path though: with `require_approval=True`, `execute_complete` calls 
`rehydrate_pydantic_output(self.output_type, ...)`, and `TypeAdapter([A, B])` 
raises `PydanticSchemaGenerationError` (a `RuntimeError` subclass) while 
`TypeAdapter(ToolOutput(A))` raises `AttributeError`. Neither is in the `except 
(ValidationError, ValueError, TypeError)` in `utils/output_type.py`, so the 
task fails after the human has approved. `A | B` works fine. Could we either 
narrow the annotation to what the operator handles (a type or a union), or 
teach `rehydrate_pydantic_output` about sequences and markers? The `:param 
output_type:` docstring still says `BaseModel` subclass too.



##########
providers/common/ai/src/airflow/providers/common/ai/mixins/hitl_review.py:
##########
@@ -35,6 +35,9 @@
 
 log = logging.getLogger(__name__)
 
+# ``hitl_timeout`` may be ``None``, so a persistently failing poll would 
otherwise loop forever.
+_MAX_CONSECUTIVE_XCOM_PULL_FAILURES = 10

Review Comment:
   The docs still only describe the old exits. The class docstring says the 
loop stops after `hitl_timeout` or `max_hitl_iterations`, and 
`docs/hitl_review.rst` says `hitl_timeout=None` "blocks until a terminal 
action", which stops being true once this limit trips. Could you update both 
here, and add the re-raised pull error to the `:raises:` of `run_hitl_review` 
while you're in there?



##########
providers/common/ai/src/airflow/providers/common/ai/operators/llm_branch.py:
##########
@@ -160,7 +160,11 @@ def __init__(
         ignore_downstream_trigger_rules: bool = False,
         **kwargs: Any,
     ) -> None:
-        kwargs.pop("output_type", None)
+        if "output_type" in kwargs:

Review Comment:
   `LLMSQLQueryOperator` has the same silent drop (`kwargs.pop("output_type", 
None)` in `llm_sql.py`) and `LLMSchemaCompareOperator` overwrites it with 
`SchemaCompareResult`. Should those get the same guard? If so, a class-level 
flag checked once in `LLMOperator.__init__` might be tidier than repeating the 
check in each subclass.



-- 
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