130 lines
3.8 KiB
Python
130 lines
3.8 KiB
Python
"""Task Center event bridge.
|
|
|
|
Converts task lifecycle actions and agent execution events into normalized AIOS
|
|
Task Center events. Uses duck-typed Agent Event Bus publisher when available and
|
|
an in-memory fallback for tests/offline runs.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import asdict, dataclass, field
|
|
from datetime import datetime, timezone
|
|
from typing import Any, Protocol
|
|
from uuid import uuid4
|
|
|
|
|
|
def utc_now() -> str:
|
|
return datetime.now(timezone.utc).isoformat()
|
|
|
|
|
|
class TaskEventPublisher(Protocol):
|
|
def publish(
|
|
self,
|
|
kind: str,
|
|
source: str,
|
|
target: str,
|
|
summary: str,
|
|
payload: dict[str, Any],
|
|
correlation_id: str | None = None,
|
|
) -> dict[str, Any]:
|
|
...
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class TaskEvent:
|
|
id: str
|
|
kind: str
|
|
source: str
|
|
target: str
|
|
summary: str
|
|
payload: dict[str, Any]
|
|
correlation_id: str | None = None
|
|
created_at: str = field(default_factory=utc_now)
|
|
|
|
def to_dict(self) -> dict[str, Any]:
|
|
return asdict(self)
|
|
|
|
|
|
class InMemoryTaskEventBus:
|
|
def __init__(self):
|
|
self.events: list[dict[str, Any]] = []
|
|
|
|
def publish(
|
|
self,
|
|
kind: str,
|
|
source: str,
|
|
target: str,
|
|
summary: str,
|
|
payload: dict[str, Any],
|
|
correlation_id: str | None = None,
|
|
) -> dict[str, Any]:
|
|
event = TaskEvent(
|
|
id=f"task_evt_{uuid4().hex[:12]}",
|
|
kind=kind,
|
|
source=source,
|
|
target=target,
|
|
summary=summary,
|
|
payload=payload,
|
|
correlation_id=correlation_id,
|
|
).to_dict()
|
|
self.events.append(event)
|
|
return event
|
|
|
|
|
|
class TaskEventBridge:
|
|
def __init__(self, bus: TaskEventPublisher | None = None):
|
|
self.bus = bus or InMemoryTaskEventBus()
|
|
|
|
def task_created(self, task: dict[str, Any]) -> dict[str, Any]:
|
|
return self.bus.publish(
|
|
kind="task_created",
|
|
source=task.get("assigned_by", "unknown"),
|
|
target=task.get("executor", "task-center"),
|
|
summary=task.get("title", "task created"),
|
|
payload=task,
|
|
correlation_id=task.get("task_id"),
|
|
)
|
|
|
|
def task_updated(self, task: dict[str, Any], action: str) -> dict[str, Any]:
|
|
return self.bus.publish(
|
|
kind="task_updated",
|
|
source=task.get("executor", "task-center"),
|
|
target="task-center",
|
|
summary=f"task {action}: {task.get('status')}",
|
|
payload={"action": action, "task": task},
|
|
correlation_id=task.get("task_id"),
|
|
)
|
|
|
|
def task_blocked(self, task: dict[str, Any], reason: str) -> dict[str, Any]:
|
|
return self.bus.publish(
|
|
kind="task_blocked",
|
|
source=task.get("executor", "unknown"),
|
|
target="owner-gate",
|
|
summary=reason,
|
|
payload={"task": task, "reason": reason},
|
|
correlation_id=task.get("task_id"),
|
|
)
|
|
|
|
def approval_requested(self, task: dict[str, Any], reason: str) -> dict[str, Any]:
|
|
return self.bus.publish(
|
|
kind="task_approval_requested",
|
|
source=task.get("executor", "unknown"),
|
|
target="owner-gate",
|
|
summary=reason,
|
|
payload={"task": task, "reason": reason},
|
|
correlation_id=task.get("task_id"),
|
|
)
|
|
|
|
def notification_sent(self, task: dict[str, Any], channel: str) -> dict[str, Any]:
|
|
return self.bus.publish(
|
|
kind="task_notification_sent",
|
|
source="notification-agent",
|
|
target=task.get("assigned_by", "owner"),
|
|
summary=f"notification sent via {channel}",
|
|
payload={"task": task, "channel": channel},
|
|
correlation_id=task.get("task_id"),
|
|
)
|
|
|
|
|
|
__all__ = ["TaskEvent", "InMemoryTaskEventBus", "TaskEventBridge"]
|