Turn a failed AgenticLens run into an acknowledged alert and incident timeline
Push a failed AgenticLens run for a deployment, let Control Tower's live detection raise a deduplicated critical alert and open an incident, acknowledge it, and read the joined incident timeline, all with the Python API and no network.
| For | Operators wiring AgenticLens results into incident response |
| Difficulty | Intermediate |
| Time | ~15 minutes |
| Capabilities | Live detection, alerts and incident views, Ecosystem evidence posture, Agent registry |
| Status | Experimental (added in 0.8.0) |
The problem
AgenticLens tells you a run failed, but that result sits in a report nobody is watching. On-call needs one alert per real failure (not one per scan), a record of who acknowledged it, and a single view of what happened, without a dashboard deciding on its own that the agent is "down" or that the problem is fixed.
Architecture
A failed run raises one critical lens.failed alert and opens an incident; rescans do not duplicate it; a later successful run clears the alert while the incident stays open.
Static diagram
sequenceDiagram
participant Lens as AgenticLens run (failed)
participant Tower as Control Tower
participant Op as On-call operator
Lens->>Tower: push native run (ingest_evidence)
Tower->>Tower: scan (every 30 s on a server)
Tower-->>Op: critical alert lens.failed + open incident
Op->>Tower: acknowledge alert
Op->>Tower: incident view (timeline)
Lens->>Tower: newer successful run
Tower->>Tower: scan clears the alert, incident stays open
Detection reads only evidence that was pushed to Tower. It never changes the health the agent reports and never runs recovery on its own.
Prerequisites
- Python 3.10 or newer.
-
Control Tower 0.8.0, installed from the repository for this walkthrough (the same version is also available on PyPI):
git clone https://github.com/DeepAgentLabs/agenticops-control-tower.git cd agenticops-control-tower python -m venv .venv && source .venv/bin/activate python -m pip install . -
No AgenticLens install, server, token or network: the run is a native JSON artifact built in the script.
Walkthrough
Save the script below as lens_alert_walkthrough.py, then run it:
python lens_alert_walkthrough.py
The numbered comments are the steps:
- Register
checkout-agentin staging with reported healthhealthy. - Push a failed AgenticLens run, observed 30 seconds ago (inside the default 300-second freshness window).
- Run a detection scan. A server does this every 30 seconds; here it is called
directly as the
writeroperator. - Scan again to show the alert is deduplicated.
- Acknowledge the alert as the on-call operator.
- Read the joined incident view.
- Push a newer successful run and scan again.
"""Turn a failed AgenticLens run into an acknowledged alert and an incident timeline."""
from datetime import datetime, timedelta, timezone
from agenticops_control_tower.config.models import Operator
from agenticops_control_tower.models import AgentRegistrationPayload, EvidenceIngestRequest
from agenticops_control_tower.snapshot import create_api
api = create_api()
operator = Operator(operator_id="on-call", role="writer")
# 1. Register the deployment. Its reported health is "healthy".
api.register(
AgentRegistrationPayload(
agent_id="checkout-agent",
name="checkout-agent",
environment="staging",
runtime="kubernetes",
framework="langgraph",
status="healthy",
capabilities={"agenticlens": "0.10.0"},
)
)
def push_lens_run(run_id: str, status: str, observed_at: datetime) -> None:
"""Push one native AgenticLens run artifact, attributed to checkout-agent."""
api.ingest_evidence(
EvidenceIngestRequest.model_validate(
{
"link": {
"agent_id": "checkout-agent",
"source": "agenticlens",
"source_version": "0.10.0",
"artifact_type": "run",
"artifact_ref": f"lens:run:{run_id}",
"run_id": run_id,
"observed_at": observed_at.isoformat(),
},
"artifact": {
"schema_version": "1.0",
"run_id": run_id,
"application_name": "checkout",
"status": status,
"task_success": status == "succeeded",
"spans": [],
},
}
)
)
now = datetime.now(timezone.utc)
# 2. AgenticLens reports a failed run.
push_lens_run("run-41", "failed", now - timedelta(seconds=30))
# 3. Scan (the server does this every 30 seconds; here we call it directly).
alert = api.operations.evaluate(operator)[0]
print("alert:", alert.rule, alert.severity, "incident:", alert.incident_id is not None)
# 4. A second scan does not duplicate the alert.
api.operations.evaluate(operator)
print("alerts after rescan:", len(api.operations.list(operator)))
# 5. Acknowledge it.
api.operations.acknowledge(alert.alert_id, operator)
# 6. Inspect the joined incident view.
view = api.operations.incident_view(alert.incident_id, operator)
print("incident state:", view["incident"].state)
print("reported health:", view["agent"].status.value)
print("timeline:", [event["event"] for event in view["timeline"]])
# 7. A newer successful run clears the alert, but the incident stays open:
# recovery still needs the approved verification workflow.
push_lens_run("run-42", "succeeded", datetime.now(timezone.utc))
api.operations.evaluate(operator)
print("active alerts:", len(api.operations.list(operator, active_only=True)))
print("cleared:", api.operations.list(operator)[0].cleared_at is not None)
print("incident state:", api.operations.incident_view(alert.incident_id, operator)["incident"].state)
Expected output
alert: lens.failed critical incident: True
alerts after rescan: 1
incident state: open
reported health: healthy
timeline: ['evidence.observed', 'alert.created', 'detected', 'alert.acknowledged']
active alerts: 0
cleared: True
incident state: open
Verify it worked
alert: lens.failed critical incident: True: one critical alert, linked to a recovery incident.alerts after rescan: 1: rescanning did not create a duplicate.reported health: healthy: the alert did not change the health the agent reports.- The timeline contains
alert.acknowledged, so the acknowledgement was recorded. - After the successful run,
active alerts: 0andcleared: True, but the incident is stillopen: clearing an alert never resolves an incident.
Clean up
The API was in memory, so nothing was stored. Remove the script and environment:
rm lens_alert_walkthrough.py
deactivate && rm -rf .venv
Variations and next steps
- On a server: push the run with
agenticops-control-tower evidence ingest checkout-agent agenticlens run.json --source-version 0.10.0 --artifact-ref lens:run:run-41 --run-id run-41(writer token), thenalerts list --active-only,alerts acknowledge ALERT_IDandincidents view INCIDENT_ID. The console shows the same alerts and timeline. - Stale or missing evidence: stop pushing, or register a capability you never
push, and the next scan raises
evidence.staleorevidence.missingwarnings. - Resolve the incident: the approved recovery workflow (investigate, preview, approve, execute, verify) is in Incident recovery.
- The repository's shorter version is
examples/live_operations.py.
Tested with
- agenticops-control-tower 0.8.0 (source, commit
36c5eb6), Python 3.13.16, Linux, base dependencies only, verified 2026-10-21. The script was run with the package onPYTHONPATH; the server-based variation was not run.