Skip to content

fix(tabular): union passthrough CSV schema and keep assistant text visible - #1302

Merged
Paul Lizer (paullizer) merged 1 commit into
microsoft:Developmentfrom
paullizer:fix/tabular-passthrough-schema-and-assistant-text
Aug 19, 2026
Merged

Paul Lizer (paullizer) merged 1 commit into
microsoft:Developmentfrom
paullizer:fix/tabular-passthrough-schema-and-assistant-text

Conversation

@paullizer

Copy link
Copy Markdown
Contributor

Summary

Two customer-reported failures in chat CSV/tabular artifact creation.

1. Passthrough CSV exports failed with a schema mismatch

Chat and workflow CSV artifacts stage already-final rows with passthrough_input_rows=True. _build_passthrough_batch_results fed those rows to _normalize_generated_batch_entries as both source and "generated" entries, so the output schema was derived from row 1 only and every later row had to match it exactly.

extract_authorized_function_result_rows merges rows from multiple action results into a single set, so field sets legitimately differ. Real failure:

Generated output schema mismatch at row 2; missing=['facts'];
unexpected=['application', 'message_metadata', 'runtime', 'schema_version']

It was then classified model_validation retryable and burned all three automatic retries in ~20 ms each -- no model runs on the passthrough path at all -- before failing the run permanently.

Fix: queue_tabular_generated_output_run unions column names across every staged passthrough batch and pins output_schema / public_output_schema / internal_checkpoint_schema up front. _build_passthrough_batch_results pads sparse rows to that schema, with a per-batch union fallback for runs queued before this change. Model-generated runs still defer to batch-1 schema discovery.

This matches build_assistant_table_csv and _build_generated_output_csv, which already unioned columns on the synchronous path.

2. The CSV artifact card hid the assistant response

hideCompletedGeneratedArtifactHandoff() adds d-none to .message-text and .message-footer when an artifact sets suppress_assistant_text. That flag exists for JSON/XML, whose payload is deliberately withheld from the streamed text (suppress_streamed_file_payload = requested_streamed_file_format in {'json', 'xml'}) and replaced with a "Generating the X file..." placeholder.

CSV was wrongly in the same set, so a full CSV narrative -- including inline charts -- was hidden the moment the card hydrated.

Fix: added ASSISTANT_TEXT_SUPPRESSING_FORMATS = {'json', 'xml'} and reused it for background structured exports. Markdown analysis artifacts keep suppress_assistant_text=True; that one is a genuine handoff.

Changes

  • application/single_app/functions_tabular_generated_exports.py -- union passthrough schema at queue time, _extend_passthrough_output_field_names, _align_passthrough_rows_to_output_fields, format-aware suppression
  • application/single_app/functions_generated_file_exports.py -- ASSISTANT_TEXT_SUPPRESSING_FORMATS
  • application/single_app/config.py -- version 0.260.005
  • functional_tests/test_tabular_passthrough_heterogeneous_rows.py -- new
  • functional_tests/test_assistant_table_csv_artifact.py -- assistant-text preservation coverage

Validation

New test_tabular_passthrough_heterogeneous_rows.py (4/4) exercises the real queue_tabular_generated_output_run and _build_passthrough_batch_results via the AST harness, with only Cosmos/blob/telemetry stubbed.

Suite Result
test_tabular_passthrough_heterogeneous_rows.py 4/4
test_assistant_table_csv_artifact.py 36/36
test_generated_json_xml_exports.py 7/7
test_tabular_background_generated_exports.py 8/8
test_tabular_queue_run_output_schema_end_to_end.py 3/3
test_tabular_row_orchestration_scale.py 15/15
test_tabular_phase5_artifact_set_lifecycle.py 4/4
test_tabular_combined_artifact_set_download_visibility.py 3/3
test_tabular_durable_artifact_lifecycle_recovery.py 5/5
test_tabular_search_analyze_artifact_matrix.py 1/1
test_tabular_shared_request_planner.py 8/8
ui_tests/test_chat_background_generated_export_status.py 7 passed, 4 skipped (no SIMPLECHAT_UI_BASE_URL)

py_compile clean, editor diagnostics clean, Windows-safe git diff --check clean.

Notes

  • Runs that already failed with the schema mismatch cannot self-heal; the request must be re-issued after deploy.
  • Release notes not updated in this PR -- happy to add an entry if preferred.

…sible

Passthrough CSV exports staged already-final rows, but
_build_passthrough_batch_results derived the output schema from row 1 only
and required every later row to match it exactly. Rows merged from multiple
action results (or records with optional fields) failed with "Generated
output schema mismatch at row N", were classified as model_validation
retries even though no model runs on this path, and the run failed after
exhausting its retries.

queue_tabular_generated_output_run now unions column names across every
staged passthrough batch and pins output_schema, public_output_schema, and
internal_checkpoint_schema up front. _build_passthrough_batch_results pads
sparse rows to that schema, falling back to a per-batch union for runs
queued before this change. Model-generated runs still defer to batch-1
schema discovery.

Also stop hiding the assistant response when a CSV artifact card renders.
suppress_assistant_text exists for JSON/XML, whose payload is withheld from
the streamed text and replaced with a placeholder. CSV narratives stream
intact, so the card must append below them instead of replacing them. Added
ASSISTANT_TEXT_SUPPRESSING_FORMATS and reused it for background structured
exports; Markdown analysis artifacts keep suppression as a real handoff.

Version: 0.260.005
@paullizer
Paul Lizer (paullizer) merged commit e1164b6 into microsoft:Development Aug 19, 2026
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant