channel.receive— inboundUnifiedMessages from pluginschannel.send— outboundUnifiedMessages to pluginschannel.event— infrastructure events from plugins
Responsibilities
Plugin spawning — On startup, the Channel Manager reads all enabledChannelConfig entries from the workspace database and spawns one subprocess per channel.
Connection handling — Plugins connect back over WebSocket using JSON-RPC 2.0. The Channel Manager accepts these connections and dispatches each incoming message by its method field.
Inbound routing — channel.receive notifications from plugins are forwarded to the on_message callback, which is the Communication Manager’s receive() method.
Event routing — channel.event notifications (such as gateway_connected or pairing_request) are forwarded to the on_event callback, which is handled directly in the server process for pairing logic.
Outbound dispatch — The Communication Manager calls send_to_channel() or broadcast() to push messages back to one or all connected plugins.
Graceful shutdown — On stop, the Channel Manager sends a channel.stop notification to each connected plugin, waits one second, then terminates any subprocesses that are still running.
Event handlers
ChannelEventHandler
A small dispatcher that maps channel-event names (e.g. pairing_request, gateway_connected, device_connected) to registered async handlers. Channel Manager forwards every inbound channel.event to it; unknown events are logged and dropped.
InfraEventHandlers
The concrete handlers registered on ChannelEventHandler. They implement the infrastructure-level reactions to plugin events: validating pairing requests and minting device attestations, tracking gateway up/down state, and updating the live recipient list when devices connect or disconnect. These responsibilities live here — not in Channel Manager — because they are security and state-management concerns rather than transport.
Inbound infrastructure events
These are channel.event notifications emitted by channel plugins and dispatched by ChannelEventHandler to InfraEventHandlers.
| Event name | Event meaning | What the handler does |
|---|---|---|
pairing_request | A device is asking to pair with this Hiro Server through the devices channel and Hiro Gate. | Validates the request, checks the active pairing session/code, creates a device ID and attestation if approved, saves the approved device, clears the pairing session, then sends pairing_response back to the devices channel. |
gateway_connected | The devices channel successfully connected to Hiro Gate. | Marks workspace runtime state as gateway-connected and records the gateway URL. |
gateway_disconnected | The devices channel lost its connection to Hiro Gate. | Marks workspace runtime state as disconnected and clears connected devices from ResourceChangeBroadcaster. |
device_connected | A device connected to Hiro Gate and is reachable through the devices channel. | Reads device_id and adds it to ResourceChangeBroadcaster’s connected recipient set. |
device_disconnected | A device disconnected from Hiro Gate and should no longer be treated as reachable. | Reads device_id and removes it from ResourceChangeBroadcaster’s connected recipient set. |
channel.event notifications sent through ChannelManager. They go directly from InfraEventHandlers to the devices channel plugin.
| Event name | Meaning | Receiver |
|---|---|---|
pairing_response | Approves or rejects a pending device pairing request. | devices channel plugin, which forwards the response to Hiro Gate and then to the device. |
Related components
CommunicationManager
The message router that sits between Channel Manager and the application core. It validates inbound messages, applies permissions, runs the adapter pipeline (transcription, persistence, …), and decides where each message goes (chat, agent, transcript, outbound queue). Channel Manager is its inbound source and its outbound sink, but every routing and policy decision is made here. See Communication Manager.
Channel plugins
The subprocesses Channel Manager spawns and talks to. Each plugin is a standalone Python package implementing the contract fromhiro-channel-sdk. The built-in devices plugin is the bridge to Hiro Gate; optional plugins such as Telegram and WhatsApp follow the same shape. See Channel Plugins.
Workspace DB (channel_plugins table)
The source of truth for which channels are enabled, how to launch them, and what configuration to push after registration. Channel Manager reads this on startup; it does not write it.
Read-only consumers
MetricsCollector, the Admin API, and the HTTP surface query Channel Manager for connected-plugin metadata and child-process info. They observe state; they do not drive the component.
See also
Channel Plugins
Wire protocol, JSON-RPC methods, plugin lifecycle, and the SDK contract.
Communication Manager
The router that makes inbound and outbound decisions across channels and the core.
UnifiedMessage reference
The shared wire contract for UnifiedMessage payloads and gateway frames.
