""" Emitter — convenience wrappers around the singleton EventBus. Deprecated-ish: prefer using `bus.emit(EventType.X, ...)` directly. These helpers exist for backward compatibility with older callers and for the CLI's `stream` command which expects simple event shapes. """ from backend.events.bus import EventBus from backend.events.schema import EventType # Process-wide singleton bus. Import this instead of constructing your own # unless you really need an isolated bus (e.g. for tests). BUS = EventBus() async def emit_pipeline(action, state, node, **extra): """Emit a pipeline/task event. `action` may be a dict (action spec) or a string (action name).""" action_name = action["name"] if isinstance(action, dict) else action node_name = node["name"] if isinstance(node, dict) else node BUS.emit( EventType.TASK_UPDATE, action=action_name, node=node_name, state=state, **extra, ) async def emit_node(node, **extra): """Emit a node state update.""" node_name = node["name"] if isinstance(node, dict) else node BUS.emit( EventType.NODE_UPDATE, node=node_name, **extra, ) async def emit_cache(action, state, node=None, **extra): """Emit a cache hit/miss event.""" action_name = action["name"] if isinstance(action, dict) else action BUS.emit( EventType.CACHE_UPDATE, action=action_name, node=node, state=state, **extra, ) async def emit_failure(action, reason, node=None, **extra): """Emit a failure event.""" action_name = action["name"] if isinstance(action, dict) else action BUS.emit( EventType.FAILURE, action=action_name, node=node, state="failed", reason=reason, **extra, ) async def emit_policy(key, value): """Emit a policy change event.""" BUS.emit( EventType.PIPELINE_UPDATE, # closest existing type action=None, node=None, state="policy", meta={"key": key, "value": value}, )