ColtenOuO opened a new pull request, #71688:
URL: https://github.com/apache/airflow/pull/71688
### Sumarry
`@task.llm`, `@task.llm_branch`, and `@task.llm_sql` all reject a non-string
`Sequence[UserContent]` prompt combined with `require_approval=True` before the
LLM ever runs, raising a `TypeError` that names the decorator the caller
actually used (e.g. `@task.llm_branch: ...`).
`@task.llm_schema_compare` was missing this decorator-level check. The same
misuse still fails before any LLM call (the underlying operator has its own
fallback guard), but the error instead names the internal
`_LLMSchemaCompareDecoratedOperator` class -- an implementation detail the
caller never wrote, which is confusing when debugging.
This adds the same `reject_sequence_with_unsupported_feature` preflight call
that the other three decorators already use, so all four give a consistent,
decorator-named error message.
### Reproduce
Reproduced by running two tasks against the same misuse
(`require_approval=True` with a `Sequence[UserContent]` prompt) -- one via
`@task.llm_branch`, one via `@task.llm_schema_compare` -- and comparing the
task logs.
```python
from __future__ import annotations
from pydantic_ai.messages import ImageUrl
from airflow.providers.standard.operators.empty import EmptyOperator
from airflow.sdk import DAG, task
with DAG(
dag_id="demo_require_approval_inconsistency",
schedule=None,
catchup=False,
):
@task.llm_branch(
llm_conn_id="demo_llm_conn",
require_approval=True,
)
def branch_with_bad_prompt():
return ["Compare these schemas:",
ImageUrl(url="https://example.com/x.png")]
@task.llm_schema_compare(
llm_conn_id="demo_llm_conn",
db_conn_ids=["demo_db_conn_a", "demo_db_conn_b"],
table_names=["demo_table"],
require_approval=True,
)
def schema_compare_with_bad_prompt():
return ["Compare these schemas:",
ImageUrl(url="https://example.com/x.png")]
branch_with_bad_prompt() >>
EmptyOperator(task_id="downstream_placeholder")
schema_compare_with_bad_prompt()
```
**Before this change:**
```
INFO - Failure caused by _LLMSchemaCompareDecoratedOperator:
require_approval=True is not supported with a non-string prompt (got list). The
approval review body renders the prompt as text; passing a
Sequence[UserContent] would expose object reprs (and any embedded bytes) in the
human review UI. Return a str prompt, or disable require_approval.
INFO - Failure caused by @task.llm_branch: Sequence[UserContent] prompts are
not supported with require_approval=True. Return a str prompt, or disable
require_approval.
```
Note the first line names `_LLMSchemaCompareDecoratedOperator` -- an
internal class the caller never wrote -- while the second names
`@task.llm_branch`, the decorator actually used.
**After this change**:
The same misuse via `@task.llm_schema_compare` instead raises:
```
@task.llm_schema_compare: Sequence[UserContent] prompts are not supported
with require_approval=True. Return a str prompt, or disable require_approval.
```
now consistent with the other three decorators.
--
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]