From 8fdaf4d3d6a877d362b8dd8deec00a9d2caaba17 Mon Sep 17 00:00:00 2001 From: uzunkuyruk Date: Sat, 9 May 2026 17:39:16 +0300 Subject: [PATCH] fix(telegram): exclude row-label column from bullet items in table rendering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a GFM table has a row-label column (first column with no header), _render_table_block_for_telegram incorrectly included the row-label cell in the bullet zip alongside the data cells, producing a spurious bullet like '• 維度: 核心賣點' before the real data rows. Detect the row-label column by comparing the first data row cell count against the header count (has_row_label_col = len(first_data_row) == len(headers) + 1). When present, use cells[0] as the heading and zip headers against cells[1:] only, correctly excluding the row-label from the bullet list. Fixes #22604 --- gateway/platforms/telegram.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/gateway/platforms/telegram.py b/gateway/platforms/telegram.py index 0ae2787debf..e680db61e67 100644 --- a/gateway/platforms/telegram.py +++ b/gateway/platforms/telegram.py @@ -180,18 +180,32 @@ def _render_table_block_for_telegram(table_block: list[str]) -> str: if len(headers) < 2: return "\n".join(table_block) + # Detect row-label column: present when data rows have one more cell + # than the header row (the row-label column carries no header). + first_data_row = _split_markdown_table_row(table_block[2]) if len(table_block) > 2 else [] + has_row_label_col = len(first_data_row) == len(headers) + 1 + rendered_rows: list[str] = [] for index, row in enumerate(table_block[2:], start=1): cells = _split_markdown_table_row(row) - if len(cells) < len(headers): - cells.extend([""] * (len(headers) - len(cells))) - elif len(cells) > len(headers): - cells = cells[: len(headers)] + if has_row_label_col: + # First cell is the row-label (heading); remaining cells align with headers. + heading = cells[0] if cells and cells[0] else f"Row {index}" + data_cells = cells[1:] + else: + # No row-label column: use first non-empty cell as heading. + heading = next((cell for cell in cells if cell), f"Row {index}") + data_cells = cells + + # Pad or trim data_cells to match headers length. + if len(data_cells) < len(headers): + data_cells.extend([""] * (len(headers) - len(data_cells))) + elif len(data_cells) > len(headers): + data_cells = data_cells[: len(headers)] - heading = next((cell for cell in cells if cell), f"Row {index}") rendered_rows.append(f"**{heading}**") rendered_rows.extend( - f"• {header}: {value}" for header, value in zip(headers, cells) + f"• {header}: {value}" for header, value in zip(headers, data_cells) ) return "\n\n".join(rendered_rows)