nodus-channels
Multi-channel messaging protocol and core types for Nodus AI systems.
Defines the standard vocabulary for multi-channel AI assistants: normalized
message types, a channel adapter protocol, a thread-safe registry, and
per-channel health monitoring. Concrete adapters (Slack, Discord, Telegram,
webhook, etc.) are separate packages that implement the ChannelAdapter
protocol.
No required external dependencies — pure stdlib.
Status: v0.1.0 — prepared, not yet published.
Install
pip install nodus-channels
What it provides
| Component | Purpose |
|---|---|
Message / Peer / Attachment / ChannelInfo |
Normalized inbound message types |
ChannelAdapter |
Protocol all concrete adapters must satisfy |
ChannelRegistry |
Thread-safe adapter registry |
HealthMonitor / HealthSnapshot / ChannelHealth |
Per-channel health tracking |
Core types
from nodus_channels import Message, Peer, Attachment, ChannelInfo
peer = Peer(id="U123", display_name="Alice", channel_id="slack")
msg = Message(
id="msg-001",
channel_id="slack",
peer=peer,
text="Hello, agent!",
attachments=[Attachment(url="https://...", media_type="image/png")],
)
info = ChannelInfo(
id="slack",
display_name="Slack",
max_message_length=4000,
supports_threads=True,
supports_attachments=True,
)
ChannelAdapter protocol
Concrete adapters implement this protocol:
from nodus_channels import ChannelAdapter, ChannelInfo, Message
from typing import AsyncIterator
class SlackAdapter:
@property
def channel_id(self) -> str: return "slack"
@property
def info(self) -> ChannelInfo:
return ChannelInfo(id="slack", display_name="Slack")
async def send(self, content: str, peer_id: str, **kwargs) -> str:
# returns message ID
...
def subscribe(self) -> AsyncIterator[Message]:
# yields inbound messages
...
assert isinstance(SlackAdapter(), ChannelAdapter) # runtime_checkable
ChannelAdapter is a @runtime_checkable Protocol — isinstance checks work
without inheritance.
ChannelRegistry
from nodus_channels import ChannelRegistry
registry = ChannelRegistry()
registry.register(slack_adapter)
registry.register(discord_adapter)
adapter = registry.get("slack") # ChannelAdapter | None
all_adapters = registry.list_all() # list[ChannelAdapter]
registry.unregister("slack")
len(registry)
Thread-safe — safe to register/unregister from multiple threads.
HealthMonitor
from nodus_channels import HealthMonitor, ChannelHealth
monitor = HealthMonitor()
monitor.record_success("slack")
monitor.record_failure("discord", reason="connection refused")
snap = monitor.snapshot("slack")
# snap.status → ChannelHealth.CONNECTED
# snap.failure_count → 0
# snap.last_error → None
snap2 = monitor.snapshot("discord")
# snap2.status → ChannelHealth.DEGRADED or DISCONNECTED
Health status transitions:
CONNECTED— no recent failuresDEGRADED— some failures, but also recent successesDISCONNECTED— only failures, no recent success
Design
- No required dependencies. Pure stdlib (
threading,dataclasses,datetime,typing). - Protocol-based.
ChannelAdapteris@runtime_checkable— adapters satisfy it by structure, not inheritance. - Thread-safe.
ChannelRegistryusesthreading.Lock.
Development
pip install -e ".[dev]"
pytest tests/ -q
License
MIT — see LICENSE.
Metadata
Release files for nodus-channels 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nodus_channels-0.1.0.tar.gz | 9.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nodus_channels-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.1 kB
Release files / nodus_channels-0.1.0.tar.gz
| Download URL | nodus_channels-0.1.0.tar.gz |
|---|---|
| Size | 9.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
47a06a2c02f798715df5b7c29b422f1cf508953f0006d924a620460508a42684
|
|
BLAKE2b-256 checksum How to use checksums |
92d0bef283208981daa614dc294deefc8a4bb90cad3ebf4464b0121ff5160e4b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|
Release files / nodus_channels-0.1.0-py3-none-any.whl
| Download URL | nodus_channels-0.1.0-py3-none-any.whl |
|---|---|
| Size | 8.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7e3746e3c07591cf9b57e62dc9a685f2c468d27c0d00ea85f2e78b11d356af54
|
|
BLAKE2b-256 checksum How to use checksums |
b69572c539e906eddcc911c661ad090ec056aa5e77fba8eb488dddb81f718062
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|