fix(gateway): resolve silence narration filter from config only (#116886)
drops process env override in delivery router so profile config is authoritative under multiplexing closes #116886
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
platform home channel ("telegram"), origin (back to where the job was created), or local (files)."""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
@@ -221,10 +220,8 @@ class DeliveryRouter:
|
||||
return path
|
||||
|
||||
def _filter_silence_narration_enabled(self) -> bool:
|
||||
"""``HERMES_FILTER_SILENCE_NARRATION`` env overrides the ``gateway.filter_silence_narration`` flag."""
|
||||
env = os.getenv("HERMES_FILTER_SILENCE_NARRATION")
|
||||
return (bool(getattr(self.config, "filter_silence_narration", True)) if env is None
|
||||
else env.strip().lower() in ("1", "true", "yes", "on"))
|
||||
"""filter silence narration based on gateway config without checking process env"""
|
||||
return bool(getattr(self.config, "filter_silence_narration", True))
|
||||
|
||||
def _cap_oversized_output(self, adapter: Any, content: str, job_id: str) -> str:
|
||||
"""Audit-save oversized cron output; truncate it for non-chunking adapters. Above MAX_PLATFORM_OUTPUT
|
||||
|
||||
@@ -77,7 +77,6 @@ class RecordingAdapter:
|
||||
@pytest.mark.asyncio
|
||||
async def test_silence_narration_dropped_pre_send(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
||||
monkeypatch.delenv("HERMES_FILTER_SILENCE_NARRATION", raising=False)
|
||||
adapter = RecordingAdapter()
|
||||
router = DeliveryRouter(GatewayConfig(), adapters={Platform.DISCORD: adapter})
|
||||
target = DeliveryTarget.parse("discord:99887766")
|
||||
@@ -95,7 +94,6 @@ async def test_silence_narration_dropped_pre_send(tmp_path, monkeypatch):
|
||||
@pytest.mark.asyncio
|
||||
async def test_config_opt_out_lets_silence_through(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
||||
monkeypatch.delenv("HERMES_FILTER_SILENCE_NARRATION", raising=False)
|
||||
adapter = RecordingAdapter()
|
||||
config = GatewayConfig(filter_silence_narration=False)
|
||||
router = DeliveryRouter(config, adapters={Platform.DISCORD: adapter})
|
||||
@@ -109,19 +107,61 @@ async def test_config_opt_out_lets_silence_through(tmp_path, monkeypatch):
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_env_override_enables_filter_over_config(tmp_path, monkeypatch):
|
||||
async def test_env_does_not_override_config_opt_out(tmp_path, monkeypatch):
|
||||
# env shouldn't override config when filter is turned off
|
||||
monkeypatch.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
||||
monkeypatch.setenv("HERMES_FILTER_SILENCE_NARRATION", "1")
|
||||
adapter = RecordingAdapter()
|
||||
# Config says off, env override forces on.
|
||||
config = GatewayConfig(filter_silence_narration=False)
|
||||
router = DeliveryRouter(config, adapters={Platform.DISCORD: adapter})
|
||||
target = DeliveryTarget.parse("discord:99887766")
|
||||
|
||||
result = await router._deliver_to_platform(target, "*(silent)*", metadata=None)
|
||||
|
||||
assert len(adapter.calls) == 1
|
||||
assert adapter.calls[0]["content"] == "*(silent)*"
|
||||
assert result == {"success": True}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_env_does_not_disable_filter_when_config_enabled(tmp_path, monkeypatch):
|
||||
# env shouldn't disable filter when config has it on
|
||||
monkeypatch.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
||||
monkeypatch.setenv("HERMES_FILTER_SILENCE_NARRATION", "0")
|
||||
adapter = RecordingAdapter()
|
||||
config = GatewayConfig(filter_silence_narration=True)
|
||||
router = DeliveryRouter(config, adapters={Platform.DISCORD: adapter})
|
||||
target = DeliveryTarget.parse("discord:99887766")
|
||||
|
||||
result = await router._deliver_to_platform(target, "*(silent)*", metadata=None)
|
||||
|
||||
assert adapter.calls == []
|
||||
assert result["filtered"] == "silence_narration"
|
||||
assert result == {
|
||||
"success": True,
|
||||
"filtered": "silence_narration",
|
||||
"delivered": False,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_multiplex_profiles_independent_silence_narration_filtering(tmp_path, monkeypatch):
|
||||
# secondary profile keeps its own setting under multiplex regardless of process env
|
||||
monkeypatch.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
||||
monkeypatch.setenv("HERMES_FILTER_SILENCE_NARRATION", "1")
|
||||
adapter_a = RecordingAdapter()
|
||||
adapter_b = RecordingAdapter()
|
||||
router_a = DeliveryRouter(GatewayConfig(filter_silence_narration=True), adapters={Platform.DISCORD: adapter_a})
|
||||
router_b = DeliveryRouter(GatewayConfig(filter_silence_narration=False), adapters={Platform.DISCORD: adapter_b})
|
||||
target = DeliveryTarget.parse("discord:99887766")
|
||||
|
||||
res_a = await router_a._deliver_to_platform(target, "*(silent)*", metadata=None)
|
||||
res_b = await router_b._deliver_to_platform(target, "*(silent)*", metadata=None)
|
||||
|
||||
assert adapter_a.calls == []
|
||||
assert res_a["filtered"] == "silence_narration"
|
||||
assert len(adapter_b.calls) == 1
|
||||
assert adapter_b.calls[0]["content"] == "*(silent)*"
|
||||
assert res_b == {"success": True}
|
||||
|
||||
|
||||
# --- Cron artifacts are exempt ----------------------------------------------
|
||||
@@ -136,7 +176,6 @@ async def test_env_override_enables_filter_over_config(tmp_path, monkeypatch):
|
||||
@pytest.mark.asyncio
|
||||
async def test_cron_job_id_metadata_bypasses_the_filter(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
||||
monkeypatch.delenv("HERMES_FILTER_SILENCE_NARRATION", raising=False)
|
||||
adapter = RecordingAdapter()
|
||||
router = DeliveryRouter(GatewayConfig(), adapters={Platform.DISCORD: adapter})
|
||||
target = DeliveryTarget.parse("discord:99887766")
|
||||
@@ -155,7 +194,6 @@ async def test_cron_job_id_metadata_bypasses_the_filter(tmp_path, monkeypatch):
|
||||
async def test_non_cron_metadata_still_filters(tmp_path, monkeypatch):
|
||||
"""The exemption keys on job_id alone — everything else is unchanged."""
|
||||
monkeypatch.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
||||
monkeypatch.delenv("HERMES_FILTER_SILENCE_NARRATION", raising=False)
|
||||
adapter = RecordingAdapter()
|
||||
router = DeliveryRouter(GatewayConfig(), adapters={Platform.DISCORD: adapter})
|
||||
target = DeliveryTarget.parse("discord:99887766")
|
||||
|
||||
Reference in New Issue
Block a user