fix(agent99): reconcile telegram lifecycle ack
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m26s
CD Pipeline / build-and-deploy (push) Successful in 14m46s
CD Pipeline / post-deploy-checks (push) Successful in 2m59s

This commit is contained in:
ogt
2026-07-15 22:18:34 +08:00
parent 441c0e971f
commit a0a5e850e1
2 changed files with 152 additions and 14 deletions

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
import asyncio
import html
from typing import Any
@@ -24,6 +25,8 @@ _SEVERITY_LABELS = {
"info": "資訊 / INFO",
}
_DURABLE_RECONCILE_DELAYS_SECONDS = (0.25, 0.5, 1.0)
def _format_lifecycle_card(payload: Agent99TelegramLifecycleRequest) -> str:
def esc(value: object) -> str:
@@ -92,21 +95,53 @@ async def deliver_agent99_telegram_lifecycle(
"""Send once through the registered AWOOOI SRE route and verify its ack."""
visual_png = payload.visual.png_bytes() if payload.visual is not None else None
response = await get_telegram_gateway().send_agent99_lifecycle_receipt(
delivery_id=payload.delivery_id,
incident_id=payload.incident_id,
state_key=payload.state_key,
text=(
gateway = get_telegram_gateway()
send_kwargs = {
"delivery_id": payload.delivery_id,
"incident_id": payload.incident_id,
"state_key": payload.state_key,
"text": (
_format_lifecycle_caption(payload)
if visual_png is not None
else _format_lifecycle_card(payload)
),
priority="P0" if payload.severity == "critical" else "P1",
project_id=payload.project_id,
reply_to_message_id=payload.reply_to_message_id,
visual_png=visual_png,
visual_sha256=(payload.visual.sha256 if payload.visual is not None else None),
"priority": "P0" if payload.severity == "critical" else "P1",
"project_id": payload.project_id,
"reply_to_message_id": payload.reply_to_message_id,
"visual_png": visual_png,
"visual_sha256": (
payload.visual.sha256 if payload.visual is not None else None
),
}
response = await gateway.send_agent99_lifecycle_receipt(**send_kwargs)
provider_send_performed = bool(
isinstance(response, dict)
and response.get("_awooop_provider_send_performed") is True
)
reconciliation_attempts = 0
# A provider send can finish before the durable outbox finalizer becomes
# readable. Re-entering with the same delivery identity only re-reads the
# send-once reservation; it cannot send a second provider message.
for delay_seconds in _DURABLE_RECONCILE_DELAYS_SECONDS:
delivery_status = (
str(response.get("_awooop_delivery_status") or "")
if isinstance(response, dict)
else ""
)
if delivery_status != "pending_unknown":
break
await asyncio.sleep(delay_seconds)
reconciliation_attempts += 1
response = await gateway.send_agent99_lifecycle_receipt(**send_kwargs)
provider_send_performed = bool(
provider_send_performed
or (
isinstance(response, dict)
and response.get("_awooop_provider_send_performed") is True
)
)
result = response.get("result") if isinstance(response, dict) else None
message_id = str(result.get("message_id") or "") if isinstance(result, dict) else ""
delivery_context = (
@@ -152,10 +187,8 @@ async def deliver_agent99_telegram_lifecycle(
"delivery_status": delivery_status or "unknown",
"durable_outbound_acknowledged": durable_ack,
"destination_binding_verified": destination_verified,
"provider_send_performed": bool(
isinstance(response, dict)
and response.get("_awooop_provider_send_performed") is True
),
"provider_send_performed": provider_send_performed,
"durable_reconciliation_attempts": reconciliation_attempts,
"visual_requested": visual_requested,
"visual_sent": visual_sent,
"visual_delivery_status": (