fix(agent99): compact callback incident ids

This commit is contained in:
ogt
2026-07-14 17:00:20 +08:00
parent 29f92f5387
commit 025829434d
2 changed files with 84 additions and 2 deletions

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
from hashlib import sha256
from typing import Any
from sqlalchemy import text
@@ -16,6 +17,18 @@ from src.services.channel_hub import (
record_external_alert_event,
)
_OPERATION_INCIDENT_ID_MAX_LENGTH = 30
def _operation_incident_id(alert_id: str | None) -> str | None:
"""Keep external alert identity while fitting the immutable event schema."""
if not alert_id:
return None
if len(alert_id) <= _OPERATION_INCIDENT_ID_MAX_LENGTH:
return alert_id
digest = sha256(alert_id.encode("utf-8")).hexdigest().upper()[:21]
return f"INC-AG99-{digest}"
async def _load_callback_readback(
*,
@@ -73,6 +86,7 @@ def _operation_context(payload: Agent99CompletionCallbackRequest) -> dict[str, A
"trace_id": payload.trace_id,
"work_item_id": payload.work_item_id,
"alert_id": payload.alert_id,
"operation_incident_id": _operation_incident_id(payload.alert_id),
"correlation_key": payload.correlation_key,
"source": payload.source,
"mode": payload.mode,
@@ -133,6 +147,7 @@ async def record_agent99_completion_callback(
else "warning"
)
context = _operation_context(payload)
operation_incident_id = _operation_incident_id(payload.alert_id)
event_id = await record_external_alert_event(
project_id=payload.project_id,
provider="agent99",
@@ -166,7 +181,7 @@ async def record_agent99_completion_callback(
if int((before or {}).get("execution_count") or 0) == 0:
await repository.append(
"EXECUTION_COMPLETED",
incident_id=payload.alert_id,
incident_id=operation_incident_id,
actor="agent99_completion_callback",
action_detail=f"{payload.mode}:{payload.outcome_state}",
success=payload.verifier_passed,
@@ -175,7 +190,7 @@ async def record_agent99_completion_callback(
if terminal_resolved and int((before or {}).get("resolved_count") or 0) == 0:
await repository.append(
"RESOLVED",
incident_id=payload.alert_id,
incident_id=operation_incident_id,
actor="agent99_completion_callback",
action_detail=f"{payload.mode}:verified_resolved",
success=True,

View File

@@ -2,6 +2,7 @@ from __future__ import annotations
# ruff: noqa: E402
import os
from hashlib import sha256
from types import SimpleNamespace
from uuid import UUID
@@ -83,6 +84,24 @@ def test_completion_payload_rejects_secret_fields_and_full_paths() -> None:
)
def test_completion_operation_incident_id_preserves_canonical_ids() -> None:
assert callback_service._operation_incident_id(None) is None
assert (
callback_service._operation_incident_id("INC-20260714-A1B2C3")
== "INC-20260714-A1B2C3"
)
def test_completion_operation_incident_id_compacts_external_ids() -> None:
external_id = "awoooi-agent99-ae36a454-c9eb-5f2d-9e35-be852b3eac9b"
expected = f"INC-AG99-{sha256(external_id.encode('utf-8')).hexdigest().upper()[:21]}"
compact = callback_service._operation_incident_id(external_id)
assert compact == expected
assert len(compact) == 30
def test_completion_callback_rejects_wrong_token(monkeypatch) -> None:
monkeypatch.setattr(settings, "AGENT99_SRE_ALERT_RELAY_TOKEN", "expected")
@@ -198,6 +217,54 @@ async def test_completion_service_writes_event_run_and_operation_receipts(monkey
assert repository.events[0][1]["context"]["raw_log_stored"] is False
@pytest.mark.asyncio
async def test_completion_service_compacts_long_alert_id_for_operation_log(
monkeypatch,
) -> None:
external_alert_id = "awoooi-agent99-ae36a454-c9eb-5f2d-9e35-be852b3eac9b"
request = Agent99CompletionCallbackRequest.model_validate(
{**payload(), "alert_id": external_alert_id}
)
event_id = UUID("3c9e8ee7-fb21-5420-afae-ef928f75a58c")
repository = FakeOperationRepository()
readbacks = iter(
[
None,
{
"event_id": str(event_id),
"run_id": "5e5b0080-e8c9-53a7-872b-0fc1ce80f11f",
"operation_count": 2,
"execution_count": 1,
"resolved_count": 1,
},
]
)
async def fake_readback(**_kwargs):
return next(readbacks)
async def fake_record_event(**_kwargs):
return event_id
monkeypatch.setattr(callback_service, "_load_callback_readback", fake_readback)
monkeypatch.setattr(callback_service, "record_external_alert_event", fake_record_event)
monkeypatch.setattr(
callback_service,
"get_alert_operation_log_repository",
lambda: repository,
)
receipt = await callback_service.record_agent99_completion_callback(request)
compact_id = callback_service._operation_incident_id(external_alert_id)
assert receipt["durable_readback"] is True
assert compact_id is not None
assert len(compact_id) == 30
assert {event[1]["incident_id"] for event in repository.events} == {compact_id}
assert repository.events[0][1]["context"]["alert_id"] == external_alert_id
assert repository.events[0][1]["context"]["operation_incident_id"] == compact_id
@pytest.mark.asyncio
async def test_completion_service_is_idempotent(monkeypatch) -> None:
request = Agent99CompletionCallbackRequest.model_validate(payload())