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"