aarmens702-hub opened a new issue, #76386:
URL: https://github.com/apache/airflow/issues/76386

   Trying `LLMFileAnalysisOperator` on a small CSV on main (5114080, common.ai 
1.1.0, macOS arm64, Python 3.12), the model gets the sample rows with their 
quotes removed. A value with a comma in it then looks like two values:
   
   ```python
   from pathlib import Path
   
   from airflow.providers.common.ai.utils.file_analysis import 
build_file_analysis_request
   
   Path("people.csv").write_text('name,city,amount\n"Smith, John","Vancouver, 
BC",120\nAlice,Toronto,80\n')
   request = build_file_analysis_request(
       file_path="people.csv", file_conn_id=None, prompt="Total amount per 
city?",
       multi_modal=False, max_files=20, max_file_size_bytes=5 * 1024 * 1024,
       max_total_size_bytes=20 * 1024 * 1024, max_text_chars=100_000, 
sample_rows=10,
   )
   print(request.user_content)
   ```
   
   ```
   Header: name, city, amount
   Sample rows:
   Smith, John, Vancouver, BC, 120
   Alice, Toronto, 80
   ```
   
   The header has 3 columns and the first row now shows 5 values, so a question 
like "total amount per city" has nothing reliable to work from. A quoted value 
with a line break in it is split across two lines the same way. This is the 
text `execute()` sends as the prompt:
   
   
https://github.com/apache/airflow/blob/51140809d2a7299955bdba51588947eeb6f015c1/providers/common/ai/src/airflow/providers/common/ai/operators/llm_file_analysis.py#L142
   
   `_render_csv` reads the file with `csv.reader`, which removes the quotes, 
then joins each row back with `", "`:
   
   
https://github.com/apache/airflow/blob/51140809d2a7299955bdba51588947eeb6f015c1/providers/common/ai/src/airflow/providers/common/ai/utils/file_analysis.py#L485-L488
   
   JSON, Parquet and Avro samples go through `dumps_masked`, so they keep their 
structure (Parquet, for example: 
[L543](https://github.com/apache/airflow/blob/51140809d2a7299955bdba51588947eeb6f015c1/providers/common/ai/src/airflow/providers/common/ai/utils/file_analysis.py#L543)).
 CSV is the only one that loses it.
   
   What I'd suggest: quote a value the way CSV does when it holds a comma, a 
quote or a line break, and leave the rest alone, so the current `alpha, 1` 
format stays the same:
   
   ```python
   def _join_csv_values(values: list[str]) -> str:
       quoted = [
           '"' + value.replace('"', '""') + '"' if any(char in value for char 
in ',"\r\n') else value
           for value in values
       ]
       return ", ".join(quoted)
   ```
   
   The first row then reads `"Smith, John", "Vancouver, BC", 120`.
   
   I tried this locally:
   - a new test in `test_file_analysis.py` (a quoted comma, an escaped quote 
and a line break) fails on main and passes with the change;
   - `test_file_analysis.py`, `test_llm_file_analysis.py` and 
`test_object_storage.py` pass (120 passed, 8 skipped because fastavro isn't 
installed);
   - running the operator itself with a `FunctionModel` that records its prompt 
shows the same thing before and after.
   
   **What should happen instead:** each CSV value should reach the model 
intact, so the sample rows have the same columns as the header.
   
   I didn't find an existing issue or PR for this. I have the fix and the test 
ready and will open a PR.
   
   ---
   Drafted-by: Claude Code (Opus 5.5); reviewed by @aarmens702-hub before 
posting
   


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