fix(relay): declare explicit relevance policy when require_mention is configured false (#69816)

Companion to gateway-gateway#160 (connector absent-row default flips to
mention-gated / requireAddress=true).

relay_relevance_policy() previously returned None whenever the projected
policy was all-falsy, on the premise that 'the connector's quiet default
already matches'. Once the connector defaults requireAddress to true,
that premise inverts for one case: an agent EXPLICITLY configured with
require_mention: false would stay silent and get mention-gated anyway,
with no way out.

The nothing-to-declare check now keys on 'require_mention is unset'
rather than 'require_mention is falsy': an explicit false IS a
configured knob and is declared to the connector; a genuinely
unconfigured platform still declares nothing and inherits the
connector's default. No wire/contract change.
This commit is contained in:
Ben Barclay 2026-07-23 13:57:57 +10:00 committed by GitHub
parent a4795da3cc
commit d8cd7ac2e7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 46 additions and 7 deletions

View file

@ -309,7 +309,9 @@ def relay_relevance_policy(platform: Optional[str] = None) -> Optional[dict]:
the ``{PLATFORM}_*`` env. ``platform`` defaults to the PRIMARY fronted
platform (back-compat). Returns the generic dict, or None when relay isn't
configured or the platform exposes no relevance knobs ( the connector's
quiet default already matches, so there's nothing to declare).
default mention-gated applies unchallenged; an EXPLICIT
``require_mention: false`` IS a knob and is declared so the connector
doesn't mention-gate an agent configured to free-respond).
"""
if platform is None:
platform, _bot_id = relay_platform_identity()
@ -351,13 +353,18 @@ def relay_relevance_policy(platform: Optional[str] = None) -> Optional[dict]:
allow_bots_env = os.environ.get(f"{platform.upper()}_ALLOW_BOTS", "").lower().strip()
allow_other_bots = allow_bots_env in {"mentions", "all"}
require_address = bool(require_mention) if require_mention is not None else False
# Nothing non-default to declare ⇒ let the connector keep its quiet default
# (matches absence-of-row semantics on the connector side).
if not require_address and not free_response and not allow_other_bots:
# Nothing CONFIGURED to declare ⇒ let the connector keep its default policy
# (mention-gated with agent-thread continuation — matches absence-of-row
# semantics on the connector side). NOTE the condition is "require_mention
# is unset", NOT "require_mention is falsy": the connector's default is now
# requireAddress=true, so an EXPLICIT `require_mention: false` is a
# non-default choice that MUST be declared or the connector would
# mention-gate an agent configured to free-respond.
if require_mention is None and not free_response and not allow_other_bots:
return None
require_address = bool(require_mention) if require_mention is not None else False
return {
"platform": platform,
"requireAddress": require_address,

View file

@ -87,12 +87,44 @@ def test_projection_falls_back_to_top_level_require_mention(monkeypatch):
def test_projection_none_when_all_default(monkeypatch):
# No require_mention, no free-response, no allow-bots ⇒ nothing to declare
# (the connector's quiet default already matches).
# (the connector's default — mention-gated — applies).
monkeypatch.setenv("GATEWAY_RELAY_PLATFORMS", "discord")
monkeypatch.setattr("gateway.run._load_gateway_config", lambda: {"discord": {}}, raising=False)
assert relay.relay_relevance_policy() is None
def test_projection_declares_explicit_require_mention_false(monkeypatch):
# An EXPLICIT `require_mention: false` is a configured (non-default) choice
# and MUST be declared: the connector's absent-row default is now
# requireAddress=true, so staying silent would mention-gate an agent the
# operator configured to free-respond.
monkeypatch.setenv("GATEWAY_RELAY_PLATFORMS", "discord")
monkeypatch.setattr(
"gateway.run._load_gateway_config",
lambda: {"discord": {"require_mention": False}},
raising=False,
)
pol = relay.relay_relevance_policy()
assert pol == {
"platform": "discord",
"requireAddress": False,
"freeResponseScopes": [],
"allowOtherBots": False,
}
def test_projection_declares_explicit_top_level_require_mention_false(monkeypatch):
# Same as above via the bridged top-level key.
monkeypatch.setenv("GATEWAY_RELAY_PLATFORMS", "discord")
monkeypatch.setattr(
"gateway.run._load_gateway_config",
lambda: {"require_mention": False},
raising=False,
)
pol = relay.relay_relevance_policy()
assert pol is not None and pol["requireAddress"] is False
def test_projection_none_when_platform_unresolved(monkeypatch):
# Default platform "relay" ⇒ no concrete fronted platform ⇒ nothing to project.
monkeypatch.setattr(