Skip to main content

nodus-router

Route inbound context to agent + session scope via fnmatch binding rules.

Maps channel/peer/thread patterns to agent IDs with priority-ordered binding rules. Resolves inbound messages to a RouteMatch containing the agent ID, a SessionKey, and the matched binding. No required external dependencies — pure stdlib with optional nodus-session integration.

Status: v0.1.0 — prepared, not yet published.


Install

pip install nodus-router

# With nodus-session SessionKey integration:
pip install "nodus-router[session]"

What it provides

Component Purpose
InboundContext Inbound message context: channel, peer, thread, roles, metadata
RouteBinding fnmatch pattern → agent_id mapping with priority
RoutingTable Thread-safe ordered list of RouteBinding objects
RouteResolver Evaluates table, returns RouteMatch (with default fallback)
RouteMatch Resolved agent_id, SessionKey, and matched binding

Quick start

from nodus_router import InboundContext, RouteBinding, RoutingTable, RouteResolver

table = RoutingTable()
table.add(RouteBinding(
    channel_pattern="slack",
    peer_pattern="*",
    agent_id="general-agent",
    priority=10,
))
table.add(RouteBinding(
    channel_pattern="slack",
    peer_pattern="U123*",
    agent_id="vip-agent",
    priority=20,   # higher priority wins
))

resolver = RouteResolver(table, default_agent_id="fallback-agent")

ctx = InboundContext(channel_id="slack", peer_id="U123456", thread_id=None)
match = resolver.resolve(ctx)

print(match.agent_id)        # "vip-agent"
print(match.session_key)     # SessionKey(agent_id="vip-agent", channel="slack", ...)
print(match.binding)         # the matched RouteBinding

InboundContext

from nodus_router import InboundContext

ctx = InboundContext(
    channel_id="slack",
    peer_id="U123456",
    thread_id="T789",    # optional
    roles=["user"],      # optional list of role strings
    metadata={},         # optional extra data
)

RouteBinding

from nodus_router import RouteBinding

binding = RouteBinding(
    channel_pattern="slack",   # fnmatch — "*" matches any channel
    peer_pattern="U123*",      # fnmatch — matches any peer starting with U123
    agent_id="vip-agent",
    priority=20,               # higher priority evaluated first
)

Patterns use fnmatch — * matches any sequence, ? matches one character.


RoutingTable

from nodus_router import RoutingTable

table = RoutingTable()
table.add(binding)
table.remove(agent_id="vip-agent")
table.list_bindings()          # list sorted by priority descending
len(table)

Thread-safe — safe to add/remove from multiple threads.


RouteResolver

from nodus_router import RouteResolver

resolver = RouteResolver(
    table,
    default_agent_id="fallback-agent",  # used when no binding matches
)

match = resolver.resolve(ctx)
# match.agent_id    — resolved agent
# match.session_key — SessionKey (from nodus-session if installed, else fallback)
# match.binding     — matched RouteBinding | None (None = default fallback)

SessionKey integration

When nodus-session is installed, RouteMatch.session_key is a real SessionKey from that package. Without it, a lightweight fallback dataclass with the same fields is used — no functionality is lost.

pip install "nodus-router[session]"

Design

  • No required dependencies. fnmatch and threading are stdlib. nodus-session is optional — a fallback SessionKey is used when absent.
  • Priority ordering. Bindings are sorted by priority descending; first match wins.
  • Thread-safe. RoutingTable uses threading.Lock.

Development

pip install -e ".[dev]"
pytest tests/ -q

License

MIT — see LICENSE.

Metadata

Release files for nodus-router 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nodus-router 0.1.0
File Size Uploaded
nodus_router-0.1.0.tar.gz 7.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nodus-router 0.1.0
File Interpreter ABI Platform
nodus_router-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 14.2 kB

Release files / nodus_router-0.1.0.tar.gz

Download URL nodus_router-0.1.0.tar.gz
Size 7.0 kB
Tags Source
SHA-256 checksum
How to use checksums
fe5374210a2ecbe7afe0fafc41e578de36e778e82ae1261e784e20204eae5772
BLAKE2b-256 checksum
How to use checksums
5cf77e28962cf3bb094cdbef0cab5158273c5d88222c20931cad4e9c6642b1de
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.9

Release files / nodus_router-0.1.0-py3-none-any.whl

Download URL nodus_router-0.1.0-py3-none-any.whl
Size 7.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
895a1bcebc264ea2551796417fa430935c7755dc128c1eec6c5143c275690acc
BLAKE2b-256 checksum
How to use checksums
1bf0c09255e60317ee8cc0451e79f84085022cea2dd0f0653bd6ba34e7a94ca2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.9

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page