hermes-agent/tests/gateway/relay
Ben Barclay 6e4e5967f7
feat(relay): multi-platform-per-agent — list identity, provision-loop, N-hello, per-frame egress (Phase 1.5) (#52830)
Cut over the agent half of Shape A (D-Q1.5a/b.1/c) to front a SET of platforms on
one relay WS:

- relay_platform_identities() parses GATEWAY_RELAY_PLATFORMS (list) +
  GATEWAY_RELAY_BOT_IDS (JSON keyed map {platform:{botId,username?}}). Cut over
  from the scalar GATEWAY_RELAY_PLATFORM/_BOT_ID (no fallback, D-Q1.5c).
- self_provision_relay() loops one /relay/provision per platform under one
  gatewayId+secret, partial-failure-tolerant.
- WebSocketRelayTransport takes the identity SET, sends one hello per identity
  (connector accumulates the advertised set), and stamps the per-frame
  OutboundFrame.platform + its matching advertised botId on outbound.
- RelayAdapter remembers each chat's underlying source.platform (mirroring the
  existing guild/dm scope capture) and tags the reply's egress platform.
- send_relay_policy() declares one relevance policy per fronted platform (the
  connector keys policy by (tenant,platform,instanceId)).

Single-platform deploys are byte-identical on the wire (1-element list, no per-frame
tag -> connector session-default fallback). typecheck/ruff clean; relay unit 221 pass
(+10 new); all 15 cross-repo E2E drivers green vs connector origin/main.
2026-06-26 17:32:46 +10:00
..
__init__.py
stub_connector.py
test_auth.py
test_contract_doc_conformance.py
test_descriptor.py
test_descriptor_from_entry.py
test_no_stub_leak.py
test_relay_adapter.py
test_relay_follow_up.py
test_relay_going_idle.py
test_relay_interrupt.py
test_relay_multiplatform.py
test_relay_passthrough.py
test_relay_policy_send.py
test_relay_registration.py
test_relay_roundtrip.py
test_relay_roundtrip_telegram.py
test_relay_sheds_crypto.py
test_self_provision.py
test_ws_transport.py