From 798227859d2e37644bebc206d19d03587f338bfb Mon Sep 17 00:00:00 2001 From: ogt Date: Fri, 17 Jul 2026 00:15:20 +0800 Subject: [PATCH] fix(telegram): label buttons by verified outcome --- apps/api/src/services/awooop_deeplinks.py | 2 +- apps/api/src/services/telegram_gateway.py | 57 ++++++++++--------- ...t_current_owner_controlled_apply_policy.py | 4 +- .../test_telegram_ai_automation_block.py | 6 +- .../tests/test_telegram_message_templates.py | 18 +++--- 5 files changed, 46 insertions(+), 41 deletions(-) diff --git a/apps/api/src/services/awooop_deeplinks.py b/apps/api/src/services/awooop_deeplinks.py index 4f0f9cdc9..838751a4a 100644 --- a/apps/api/src/services/awooop_deeplinks.py +++ b/apps/api/src/services/awooop_deeplinks.py @@ -47,7 +47,7 @@ def incident_truth_chain_button_row( "url": incident_alerts_url(incident_id, project_id=project_id), }, { - "text": "🧭 Runs", + "text": "🧭 執行鏈", "url": incident_runs_url(incident_id, project_id=project_id), }, ] diff --git a/apps/api/src/services/telegram_gateway.py b/apps/api/src/services/telegram_gateway.py index 89fcfec30..8f2088cd3 100644 --- a/apps/api/src/services/telegram_gateway.py +++ b/apps/api/src/services/telegram_gateway.py @@ -157,6 +157,11 @@ _ACTUAL_BOT_ALIAS_KEY = "_awoooi_actual_bot_alias" _DELIVERY_CONTEXT_KEY = "_awoooi_delivery_context" _BINARY_UPLOAD_KEY = "_awoooi_binary_upload" _CANONICAL_SRE_DESTINATION = "telegram_chat_alias:awoooi_sre_war_room" +_BUTTON_LABEL_EVIDENCE = "🧰 AI 處置證據" +_BUTTON_LABEL_REANALYZE = "🔄 重新診斷" +_BUTTON_LABEL_HISTORY = "📈 復發趨勢" +_BUTTON_LABEL_WORK_ITEM = "🧾 受控工作項" +_BUTTON_LABEL_RUNS = "🧭 執行鏈" _GUARDED_TELEGRAM_BOT_METHODS = frozenset( { "sendMessage", @@ -1551,11 +1556,11 @@ def _format_manual_handoff_package_lines( if not compact: if work_item_deep_link: lines.append( - "按鈕:Work Item 開啟受控佇列," - "處置包 看完整證據,Runs 追蹤狀態" + "按鈕:受控工作項 開啟受控佇列," + "AI 處置證據 查完整回執,執行鏈 追蹤狀態" ) else: - lines.append("按鈕:處置包 看完整證據,重診 重新收集,Runs 追蹤狀態") + lines.append("按鈕:AI 處置證據 查完整回執,重新診斷 重收證據,執行鏈 追蹤狀態") return lines @@ -1605,7 +1610,7 @@ def _awooop_runs_button_row(incident_id: str) -> list[dict[str, str]]: if not incident_id: return [] return [{ - "text": "🧭 Runs", + "text": _BUTTON_LABEL_RUNS, "url": _awooop_runs_url_for_incident(incident_id), }] @@ -7414,11 +7419,11 @@ class TelegramGateway: repair_candidate_work_item_id=repair_candidate_work_item_id, ) if work_item_deep_link: - first_row.append({"text": "🧾 Work Item", "url": work_item_deep_link}) + first_row.append({"text": _BUTTON_LABEL_WORK_ITEM, "url": work_item_deep_link}) first_row.extend( [ - {"text": "🧰 處置包", "callback_data": f"detail:{incident_id}"}, - {"text": "📊 歷史", "callback_data": f"history:{incident_id}"}, + {"text": _BUTTON_LABEL_EVIDENCE, "callback_data": f"detail:{incident_id}"}, + {"text": _BUTTON_LABEL_HISTORY, "callback_data": f"history:{incident_id}"}, ] ) rows.append(first_row) @@ -7450,15 +7455,15 @@ class TelegramGateway: ) if work_item_deep_link: info_row.append({ - "text": "🧾 Work Item", + "text": _BUTTON_LABEL_WORK_ITEM, "url": work_item_deep_link, }) info_row.extend([ - {"text": "🧰 處置包", "callback_data": f"detail:{incident_id}"}, + {"text": _BUTTON_LABEL_EVIDENCE, "callback_data": f"detail:{incident_id}"}, ]) secondary_row.extend([ - {"text": "🔄 重診", "callback_data": f"reanalyze:{incident_id}"}, - {"text": "📊 歷史", "callback_data": f"history:{incident_id}"}, + {"text": _BUTTON_LABEL_REANALYZE, "callback_data": f"reanalyze:{incident_id}"}, + {"text": _BUTTON_LABEL_HISTORY, "callback_data": f"history:{incident_id}"}, {"text": "🔕 靜默", "callback_data": silence_nonce}, ]) else: @@ -7545,7 +7550,7 @@ class TelegramGateway: rows += [category_btns[i:i+3] for i in range(0, len(category_btns), 3)] # 通用操作:[詳情] [忽略] rows.append([ - {"text": "📋 詳情", "callback_data": f"detail:{incident_id}"}, + {"text": _BUTTON_LABEL_EVIDENCE, "callback_data": f"detail:{incident_id}"}, {"text": "🔕 忽略", "callback_data": silence_nonce}, ]) awooop_row = _awooop_truth_chain_button_row(incident_id) @@ -7564,9 +7569,9 @@ class TelegramGateway: # 第二行: 資訊查詢按鈕 (ADR-050: read-only, format: action:incident_id) if incident_id: buttons.append([ - {"text": "📋 詳情", "callback_data": f"detail:{incident_id}"}, - {"text": "🔄 重診", "callback_data": f"reanalyze:{incident_id}"}, - {"text": "📊 歷史", "callback_data": f"history:{incident_id}"}, + {"text": _BUTTON_LABEL_EVIDENCE, "callback_data": f"detail:{incident_id}"}, + {"text": _BUTTON_LABEL_REANALYZE, "callback_data": f"reanalyze:{incident_id}"}, + {"text": _BUTTON_LABEL_HISTORY, "callback_data": f"history:{incident_id}"}, ]) awooop_row = _awooop_truth_chain_button_row(incident_id) if awooop_row: @@ -8250,8 +8255,8 @@ class TelegramGateway: # read-only 查類按鈕(2-part info 格式,handler 已在 handle_callback 實作) # detail/history 均在 INFO_ACTIONS 白名單,無 nonce 無副作用 inline_keyboard = [[ - {"text": "📋 詳情", "callback_data": f"detail:{incident_id}"}, - {"text": "📊 歷史", "callback_data": f"history:{incident_id}"}, + {"text": _BUTTON_LABEL_EVIDENCE, "callback_data": f"detail:{incident_id}"}, + {"text": _BUTTON_LABEL_HISTORY, "callback_data": f"history:{incident_id}"}, ]] awooop_row = _awooop_truth_chain_button_row(incident_id) if awooop_row: @@ -10938,9 +10943,9 @@ class TelegramGateway: if keep_info_buttons: inline_keyboard = [ [ - {"text": "📋 詳情", "callback_data": f"detail:{incident_id}"}, - {"text": "🔄 重診", "callback_data": f"reanalyze:{incident_id}"}, - {"text": "📊 歷史", "callback_data": f"history:{incident_id}"}, + {"text": _BUTTON_LABEL_EVIDENCE, "callback_data": f"detail:{incident_id}"}, + {"text": _BUTTON_LABEL_REANALYZE, "callback_data": f"reanalyze:{incident_id}"}, + {"text": _BUTTON_LABEL_HISTORY, "callback_data": f"history:{incident_id}"}, ], ] awooop_row = _awooop_truth_chain_button_row(incident_id) @@ -13759,23 +13764,23 @@ class TelegramGateway: ) if work_item_deep_link: no_action_first_row.append({ - "text": "🧾 Work Item", + "text": _BUTTON_LABEL_WORK_ITEM, "url": work_item_deep_link, }) no_action_first_row.append( - {"text": "🧰 處置包", "callback_data": f"detail:{incident_id}"} + {"text": _BUTTON_LABEL_EVIDENCE, "callback_data": f"detail:{incident_id}"} ) info_buttons = [ no_action_first_row, [ - {"text": "🔄 重診", "callback_data": f"reanalyze:{incident_id}"}, - {"text": "📊 歷史", "callback_data": f"history:{incident_id}"}, + {"text": _BUTTON_LABEL_REANALYZE, "callback_data": f"reanalyze:{incident_id}"}, + {"text": _BUTTON_LABEL_HISTORY, "callback_data": f"history:{incident_id}"}, ], ] else: info_buttons = [[ - {"text": "📋 詳情", "callback_data": f"detail:{incident_id}"}, - {"text": "📊 歷史", "callback_data": f"history:{incident_id}"}, + {"text": _BUTTON_LABEL_EVIDENCE, "callback_data": f"detail:{incident_id}"}, + {"text": _BUTTON_LABEL_HISTORY, "callback_data": f"history:{incident_id}"}, ]] awooop_row = _awooop_truth_chain_button_row(incident_id) if awooop_row: diff --git a/apps/api/tests/test_current_owner_controlled_apply_policy.py b/apps/api/tests/test_current_owner_controlled_apply_policy.py index 328e53728..2149ad658 100644 --- a/apps/api/tests/test_current_owner_controlled_apply_policy.py +++ b/apps/api/tests/test_current_owner_controlled_apply_policy.py @@ -125,8 +125,8 @@ async def test_controlled_automation_keyboard_has_no_approval_buttons() -> None: assert "✅ 批准" not in button_texts assert "❌ 拒絕" not in button_texts - assert "🧰 處置包" in button_texts - assert "📊 歷史" in button_texts + assert "🧰 AI 處置證據" in button_texts + assert "📈 復發趨勢" in button_texts def _approval_record(*, action: str, risk_level: RiskLevel) -> SimpleNamespace: diff --git a/apps/api/tests/test_telegram_ai_automation_block.py b/apps/api/tests/test_telegram_ai_automation_block.py index 4ddbaab1b..40b3112ca 100644 --- a/apps/api/tests/test_telegram_ai_automation_block.py +++ b/apps/api/tests/test_telegram_ai_automation_block.py @@ -85,8 +85,8 @@ def test_repair_candidate_missing_card_exposes_ai_repair_candidate_package() -> assert "排程/監控:Observability" in body assert "Verifier:事件時間線" in body assert "不可視為自動化完成" in body - assert "按鈕:Work Item 開啟受控佇列" in body - assert "處置包 看完整證據" in body + assert "按鈕:受控工作項 開啟受控佇列" in body + assert "AI 處置證據 查完整回執" in body assert "修復候選狀態" in body assert "等待人工批准" not in body @@ -150,7 +150,7 @@ def test_repair_candidate_draft_ready_card_exposes_controlled_queue_handoff() -> assert "promotion=11/11" in body assert "AwoooP 修復候選草案" in body assert "自動化資產總帳" in body - assert "按鈕:Work Item 開啟受控佇列" in body + assert "按鈕:受控工作項 開啟受控佇列" in body assert "缺少可執行修復候選" not in body assert "等待人工批准" not in body diff --git a/apps/api/tests/test_telegram_message_templates.py b/apps/api/tests/test_telegram_message_templates.py index 91fc24524..366ce7d5a 100644 --- a/apps/api/tests/test_telegram_message_templates.py +++ b/apps/api/tests/test_telegram_message_templates.py @@ -1715,7 +1715,7 @@ def test_awooop_reply_markup_prefers_truth_chain_then_runs() -> None: ), }, { - "text": "🧭 Runs", + "text": "🧭 執行鏈", "url": ( "https://awoooi.wooo.work/zh-TW/awooop/runs" "?project_id=awoooi&incident_id=INC-20260514-F85F21" @@ -1749,7 +1749,7 @@ async def test_build_inline_keyboard_includes_awooop_deep_link() -> None: ), } in buttons assert { - "text": "🧭 Runs", + "text": "🧭 執行鏈", "url": ( "https://awoooi.wooo.work/zh-TW/awooop/runs" "?project_id=awoooi&incident_id=INC-20260514-F85F21" @@ -1777,11 +1777,11 @@ async def test_build_inline_keyboard_hides_approval_for_no_action() -> None: assert "✅ 批准" not in button_texts assert "❌ 拒絕" not in button_texts - assert "🧰 處置包" in button_texts - assert "🔄 重診" in button_texts + assert "🧰 AI 處置證據" in button_texts + assert "🔄 重新診斷" in button_texts assert "🔕 靜默" in button_texts assert { - "text": "🧭 Runs", + "text": "🧭 執行鏈", "url": ( "https://awoooi.wooo.work/zh-TW/awooop/runs" "?project_id=awoooi&incident_id=INC-20260611-NOOP" @@ -1818,17 +1818,17 @@ async def test_build_inline_keyboard_links_work_item_for_no_action_handoff() -> assert "✅ 批准" not in button_texts assert "❌ 拒絕" not in button_texts assert { - "text": "🧾 Work Item", + "text": "🧾 受控工作項", "url": ( "https://awoooi.wooo.work/zh-TW/awooop/work-items" "?project_id=awoooi&incident_id=INC-20260625-977E5F" "&work_item_id=repair-candidate-draft%3Aawoooi%3AINC-20260625-977E5F" ), } in buttons - assert "🧰 處置包" in button_texts - assert "🔄 重診" in button_texts + assert "🧰 AI 處置證據" in button_texts + assert "🔄 重新診斷" in button_texts assert { - "text": "🧭 Runs", + "text": "🧭 執行鏈", "url": ( "https://awoooi.wooo.work/zh-TW/awooop/runs" "?project_id=awoooi&incident_id=INC-20260625-977E5F"