Merge remote dev branch

This commit is contained in:
Alex Blank
2026-05-29 12:55:03 +02:00
6 changed files with 690 additions and 24 deletions
+34
View File
@@ -15,6 +15,7 @@ from src.models.tool_instance import ToolInstance
from src.services.correlation import get_correlation_id
from src.services.docker import check_tunnel_health, get_container_status
from src.services.event_bus import InstanceEventBus, InstanceEventPayload
from src.services.notification_service import notification_service
logger = logging.getLogger(__name__)
@@ -217,3 +218,36 @@ class HealthMonitor:
}
await self._event_bus.publish(event_type, payload)
# Create notification for instance owner (fire-and-forget)
if new_status == "error":
category = "instance"
severity = "error"
title = "Container failed"
else:
category = "health"
if new_status == "unhealthy":
severity = "warning"
title = "Container unhealthy"
else:
severity = "info"
title = "Container recovered"
try:
await notification_service.create_notification(
session=session,
user_id=instance.owner_id,
category=category,
severity=severity,
title=title,
message=message,
source_type="tool_instances",
source_id=instance.id,
metadata=metadata,
)
except Exception:
logger.exception(
"Failed to create notification for health event %s",
event_type,
extra={"correlation_id": correlation_id},
)
+43
View File
@@ -1,5 +1,6 @@
"""Lifecycle hook helpers for instrumenting tool instance transitions."""
import logging
import uuid
from datetime import datetime, timezone
@@ -9,6 +10,25 @@ from src.models.instance_event import InstanceEvent
from src.models.tool_instance import ToolInstance
from src.services.correlation import get_correlation_id
from src.services.event_bus import InstanceEventBus, InstanceEventPayload
from src.services.notification_service import notification_service
logger = logging.getLogger(__name__)
def _derive_title(event_type: str) -> str:
"""Map lifecycle event type to a human-readable notification title."""
mapping = {
"instance.created": "Container created",
"instance.started": "Container started",
"instance.stopped": "Container stopped",
"instance.restarted": "Container restarted",
"instance.deleted": "Container deleted",
"instance.error": "Container error",
}
return mapping.get(
event_type,
event_type.replace("instance.", "").replace("_", " ").title(),
)
def _build_payload(
@@ -96,3 +116,26 @@ async def publish_lifecycle_event(
# Publish to bus
await event_bus.publish(event_type, payload)
# Create notification for instance owner (fire-and-forget)
severity = "error" if event_type == "instance.error" else "info"
title = _derive_title(event_type)
try:
await notification_service.create_notification(
session=session,
user_id=instance.owner_id,
category="instance",
severity=severity,
title=title,
message=message,
source_type="tool_instances",
source_id=instance.id,
metadata=metadata,
)
except Exception:
logger.exception(
"Failed to create notification for lifecycle event %s",
event_type,
extra={"correlation_id": payload.get("correlation_id", "unknown")},
)