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)."""
|
platform home channel ("telegram"), origin (back to where the job was created), or local (files)."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@@ -221,10 +220,8 @@ class DeliveryRouter:
|
|||||||
return path
|
return path
|
||||||
|
|
||||||
def _filter_silence_narration_enabled(self) -> bool:
|
def _filter_silence_narration_enabled(self) -> bool:
|
||||||
"""``HERMES_FILTER_SILENCE_NARRATION`` env overrides the ``gateway.filter_silence_narration`` flag."""
|
"""filter silence narration based on gateway config without checking process env"""
|
||||||
env = os.getenv("HERMES_FILTER_SILENCE_NARRATION")
|
return bool(getattr(self.config, "filter_silence_narration", True))
|
||||||
return (bool(getattr(self.config, "filter_silence_narration", True)) if env is None
|
|
||||||
else env.strip().lower() in ("1", "true", "yes", "on"))
|
|
||||||
|
|
||||||
def _cap_oversized_output(self, adapter: Any, content: str, job_id: str) -> str:
|
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
|
"""Audit-save oversized cron output; truncate it for non-chunking adapters. Above MAX_PLATFORM_OUTPUT
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ class RecordingAdapter:
|
|||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_silence_narration_dropped_pre_send(tmp_path, monkeypatch):
|
async def test_silence_narration_dropped_pre_send(tmp_path, monkeypatch):
|
||||||
monkeypatch.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
monkeypatch.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
||||||
monkeypatch.delenv("HERMES_FILTER_SILENCE_NARRATION", raising=False)
|
|
||||||
adapter = RecordingAdapter()
|
adapter = RecordingAdapter()
|
||||||
router = DeliveryRouter(GatewayConfig(), adapters={Platform.DISCORD: adapter})
|
router = DeliveryRouter(GatewayConfig(), adapters={Platform.DISCORD: adapter})
|
||||||
target = DeliveryTarget.parse("discord:99887766")
|
target = DeliveryTarget.parse("discord:99887766")
|
||||||
@@ -95,7 +94,6 @@ async def test_silence_narration_dropped_pre_send(tmp_path, monkeypatch):
|
|||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_config_opt_out_lets_silence_through(tmp_path, monkeypatch):
|
async def test_config_opt_out_lets_silence_through(tmp_path, monkeypatch):
|
||||||
monkeypatch.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
monkeypatch.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
||||||
monkeypatch.delenv("HERMES_FILTER_SILENCE_NARRATION", raising=False)
|
|
||||||
adapter = RecordingAdapter()
|
adapter = RecordingAdapter()
|
||||||
config = GatewayConfig(filter_silence_narration=False)
|
config = GatewayConfig(filter_silence_narration=False)
|
||||||
router = DeliveryRouter(config, adapters={Platform.DISCORD: adapter})
|
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
|
@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.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
||||||
monkeypatch.setenv("HERMES_FILTER_SILENCE_NARRATION", "1")
|
monkeypatch.setenv("HERMES_FILTER_SILENCE_NARRATION", "1")
|
||||||
adapter = RecordingAdapter()
|
adapter = RecordingAdapter()
|
||||||
# Config says off, env override forces on.
|
|
||||||
config = GatewayConfig(filter_silence_narration=False)
|
config = GatewayConfig(filter_silence_narration=False)
|
||||||
router = DeliveryRouter(config, adapters={Platform.DISCORD: adapter})
|
router = DeliveryRouter(config, adapters={Platform.DISCORD: adapter})
|
||||||
target = DeliveryTarget.parse("discord:99887766")
|
target = DeliveryTarget.parse("discord:99887766")
|
||||||
|
|
||||||
result = await router._deliver_to_platform(target, "*(silent)*", metadata=None)
|
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 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 ----------------------------------------------
|
# --- Cron artifacts are exempt ----------------------------------------------
|
||||||
@@ -136,7 +176,6 @@ async def test_env_override_enables_filter_over_config(tmp_path, monkeypatch):
|
|||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_cron_job_id_metadata_bypasses_the_filter(tmp_path, monkeypatch):
|
async def test_cron_job_id_metadata_bypasses_the_filter(tmp_path, monkeypatch):
|
||||||
monkeypatch.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
monkeypatch.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
||||||
monkeypatch.delenv("HERMES_FILTER_SILENCE_NARRATION", raising=False)
|
|
||||||
adapter = RecordingAdapter()
|
adapter = RecordingAdapter()
|
||||||
router = DeliveryRouter(GatewayConfig(), adapters={Platform.DISCORD: adapter})
|
router = DeliveryRouter(GatewayConfig(), adapters={Platform.DISCORD: adapter})
|
||||||
target = DeliveryTarget.parse("discord:99887766")
|
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):
|
async def test_non_cron_metadata_still_filters(tmp_path, monkeypatch):
|
||||||
"""The exemption keys on job_id alone — everything else is unchanged."""
|
"""The exemption keys on job_id alone — everything else is unchanged."""
|
||||||
monkeypatch.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
monkeypatch.setattr("gateway.delivery.get_hermes_home", lambda: tmp_path)
|
||||||
monkeypatch.delenv("HERMES_FILTER_SILENCE_NARRATION", raising=False)
|
|
||||||
adapter = RecordingAdapter()
|
adapter = RecordingAdapter()
|
||||||
router = DeliveryRouter(GatewayConfig(), adapters={Platform.DISCORD: adapter})
|
router = DeliveryRouter(GatewayConfig(), adapters={Platform.DISCORD: adapter})
|
||||||
target = DeliveryTarget.parse("discord:99887766")
|
target = DeliveryTarget.parse("discord:99887766")
|
||||||
|
|||||||
Reference in New Issue
Block a user