feat(telegram): show callback owner review triage
All checks were successful
CD Pipeline / tests (push) Successful in 1m11s
Code Review / ai-code-review (push) Successful in 12s
CD Pipeline / build-and-deploy (push) Successful in 4m11s
CD Pipeline / post-deploy-checks (push) Successful in 1m29s

This commit is contained in:
Your Name
2026-05-25 09:01:50 +08:00
parent b466674621
commit eeece58c0d
2 changed files with 135 additions and 1 deletions

View File

@@ -479,9 +479,79 @@ def _format_km_stale_completion_lines(summary: dict[str, object] | None) -> list
else:
lines.append("此事件: <code>no_related_owner_review</code>")
lines.append("下一步: <code>review_awooop_completion_queue</code>")
triage = _km_stale_completion_triage(summary)
if triage:
support = triage.get("supporting_agents")
support_text = (
" / ".join(str(item) for item in support[:3])
if isinstance(support, list)
else "--"
)
lines += [
(
"流程: "
f"<code>{html.escape(str(triage.get('flow_stage') or '--'))}</code>"
" / 匹配 "
f"<code>{html.escape(str(triage.get('matching_strategy') or '--'))}</code>"
),
(
"主責: "
f"<code>{html.escape(str(triage.get('ai_lead_agent') or '--'))}</code>"
" / 協作 "
f"<code>{html.escape(support_text)}</code>"
),
(
"自動化: "
f"<code>{html.escape(str(triage.get('automation_state') or '--'))}</code>"
" / safe-auto "
f"<code>{html.escape(_bool_code(triage.get('safe_to_auto_repair')))}</code>"
),
(
"卡點: "
f"<code>{html.escape(str(triage.get('blocking_reason') or '--'))}</code>"
),
]
return lines
def _km_stale_completion_triage(
summary: dict[str, object],
) -> dict[str, object] | None:
triage = summary.get("triage")
if isinstance(triage, dict):
return triage
work_item = summary.get("work_item")
if isinstance(work_item, dict) and isinstance(work_item.get("triage"), dict):
return work_item["triage"]
return None
def _build_km_stale_callback_owner_review_triage(
*,
reason: str,
) -> dict[str, object]:
return {
"schema_version": "km_stale_callback_owner_review_triage_v1",
"flow_stage": "callback_observed_owner_review_link_missing",
"ai_lead_agent": "Hermes",
"supporting_agents": ["OpenClaw", "ElephantAlpha"],
"automation_state": "manual_owner_review_required",
"safe_to_auto_repair": False,
"blocking_reason": reason,
"matching_strategy": "related_incident_id_exact_match",
"already_done": [
"callback_reply_persisted",
"completion_queue_checked",
"telegram_detail_history_rendered",
],
"next_actions": [
"review_awooop_callback_work_item",
"queue_matching_km_stale_candidate",
"complete_owner_review_after_owner_approval",
],
}
async def _fetch_km_stale_completion_summary_for_incident(
*,
incident_id: str,
@@ -508,11 +578,33 @@ async def _fetch_km_stale_completion_summary_for_incident(
for item in queue.items
if item.related_incident_id == incident_id
]
status_value = "matched_owner_review" if items else "no_related_owner_review"
reason = None if items else "no_matching_completion_item"
triage = (
None
if items
else _build_km_stale_callback_owner_review_triage(reason=reason)
)
work_item = None
if triage:
work_item = {
"schema_version": "km_stale_callback_owner_review_work_item_v1",
"kind": "km_stale_callback_owner_review",
"status": "open",
"incident_id": incident_id,
"reason": reason,
"next_step": "review_or_queue_km_owner_review",
"triage": triage,
"writes_on_read": False,
"manual_review_required": True,
"batch_writes_allowed": False,
}
return {
"schema_version": "km_stale_owner_review_completion_telegram_summary_v1",
"status": "ok",
"status": status_value,
"project_id": project_id or "awoooi",
"incident_id": incident_id,
"missing_reason": reason,
"total": queue.total,
"returned": queue.returned,
"pending_count": queue.pending_count,
@@ -524,6 +616,8 @@ async def _fetch_km_stale_completion_summary_for_incident(
"batch_writes_allowed": queue.batch_writes_allowed,
"manual_review_required": queue.manual_review_required,
"items": items[:5],
"triage": triage,
"work_item": work_item,
}
except Exception as exc:
logger.debug(

View File

@@ -206,6 +206,46 @@ def test_km_stale_completion_lines_show_owner_review_queue_state() -> None:
assert "preview_stale_km_review_completion" in joined
def test_km_stale_completion_lines_show_callback_triage_state() -> None:
"""詳情/歷史要顯示 callback owner-review 缺口的流程、主責與卡點。"""
lines = telegram_gateway_module._format_km_stale_completion_lines({
"schema_version": "km_stale_owner_review_completion_telegram_summary_v1",
"status": "no_related_owner_review",
"incident_id": "INC-20260524-16109D",
"ready_count": 10,
"blocked_count": 0,
"completed_count": 1,
"failed_count": 0,
"writes_on_read": False,
"batch_writes_allowed": False,
"items": [],
"work_item": {
"schema_version": "km_stale_callback_owner_review_work_item_v1",
"status": "open",
"triage": {
"schema_version": "km_stale_callback_owner_review_triage_v1",
"flow_stage": "callback_observed_owner_review_link_missing",
"ai_lead_agent": "Hermes",
"supporting_agents": ["OpenClaw", "ElephantAlpha"],
"automation_state": "manual_owner_review_required",
"safe_to_auto_repair": False,
"blocking_reason": "no_matching_completion_item",
"matching_strategy": "related_incident_id_exact_match",
},
},
})
joined = "\n".join(lines)
assert "no_related_owner_review" in joined
assert "callback_observed_owner_review_link_missing" in joined
assert "related_incident_id_exact_match" in joined
assert "Hermes" in joined
assert "OpenClaw / ElephantAlpha" in joined
assert "manual_owner_review_required" in joined
assert "safe-auto <code>no</code>" in joined
assert "no_matching_completion_item" in joined
def test_awooop_runs_url_for_incident_uses_public_incident_filter() -> None:
"""Telegram URL button 必須導到公開 AwoooP Run list並帶 incident filter。"""
url = telegram_gateway_module._awooop_runs_url_for_incident("INC-20260514-F85F21")