mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-08 13:12:08 +00:00
fix: preserve busy steer env override
This commit is contained in:
parent
12f03b11ff
commit
d111faa3a7
2 changed files with 49 additions and 10 deletions
|
|
@ -1563,8 +1563,16 @@ if _config_path.exists():
|
|||
os.environ["HERMES_GATEWAY_BUSY_TEXT_MODE"] = str(_display_cfg["busy_text_mode"])
|
||||
if "busy_ack_enabled" in _display_cfg:
|
||||
os.environ["HERMES_GATEWAY_BUSY_ACK_ENABLED"] = str(_display_cfg["busy_ack_enabled"])
|
||||
if "busy_steer_ack_enabled" in _display_cfg:
|
||||
os.environ["HERMES_GATEWAY_BUSY_STEER_ACK_ENABLED"] = str(_display_cfg["busy_steer_ack_enabled"])
|
||||
# This process-level env var is documented as an override for
|
||||
# service managers, so preserve it when already set. Other display
|
||||
# bridges stay config-authoritative for backwards compatibility.
|
||||
if (
|
||||
"busy_steer_ack_enabled" in _display_cfg
|
||||
and "HERMES_GATEWAY_BUSY_STEER_ACK_ENABLED" not in os.environ
|
||||
):
|
||||
os.environ["HERMES_GATEWAY_BUSY_STEER_ACK_ENABLED"] = str(
|
||||
_display_cfg["busy_steer_ack_enabled"]
|
||||
)
|
||||
# Timezone: bridge config.yaml → HERMES_TIMEZONE env var.
|
||||
_tz_cfg = _cfg.get("timezone", "")
|
||||
if _tz_cfg and isinstance(_tz_cfg, str):
|
||||
|
|
@ -5332,6 +5340,15 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew
|
|||
logger.debug("Busy ack suppressed for session %s", session_key)
|
||||
return True # input still processed, just no ack sent
|
||||
|
||||
# Debounce before consulting config-heavy display settings. Rapid
|
||||
# follow-ups should be processed but should not trigger another config
|
||||
# read just to discover that no ack will be sent.
|
||||
_BUSY_ACK_COOLDOWN = 30
|
||||
now = time.time()
|
||||
last_ack = self._busy_ack_ts.get(session_key, 0)
|
||||
if now - last_ack < _BUSY_ACK_COOLDOWN:
|
||||
return True # interrupt sent (if not queue), ack already delivered recently
|
||||
|
||||
from gateway.display_config import resolve_display_setting
|
||||
platform_key = _platform_config_key(event.source.platform)
|
||||
|
||||
|
|
@ -5356,14 +5373,6 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew
|
|||
logger.debug("Busy steer ack suppressed for session %s", session_key)
|
||||
return True
|
||||
|
||||
# Debounce: only send an acknowledgment once every 30 seconds per session
|
||||
# to avoid spamming the user when they send multiple messages quickly
|
||||
_BUSY_ACK_COOLDOWN = 30
|
||||
now = time.time()
|
||||
last_ack = self._busy_ack_ts.get(session_key, 0)
|
||||
if now - last_ack < _BUSY_ACK_COOLDOWN:
|
||||
return True # interrupt sent (if not queue), ack already delivered recently
|
||||
|
||||
self._busy_ack_ts[session_key] = now
|
||||
|
||||
# Build a status-rich acknowledgment. Mobile chat defaults keep this
|
||||
|
|
|
|||
|
|
@ -358,6 +358,36 @@ class TestBusySessionAck:
|
|||
adapter._send_with_retry.assert_not_called()
|
||||
assert sk not in adapter._pending_messages
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_busy_ack_debounce_skips_steer_ack_config_load(self, monkeypatch):
|
||||
"""Rapid follow-ups should not reload display config when ack is debounced."""
|
||||
import gateway.run as _gr
|
||||
|
||||
def _boom():
|
||||
raise AssertionError("config should not be loaded inside ack cooldown")
|
||||
|
||||
monkeypatch.delenv("HERMES_GATEWAY_BUSY_STEER_ACK_ENABLED", raising=False)
|
||||
monkeypatch.setattr(_gr, "_load_gateway_config", _boom)
|
||||
|
||||
runner, sentinel = _make_runner()
|
||||
runner._busy_input_mode = "steer"
|
||||
adapter = _make_adapter()
|
||||
|
||||
event = _make_event(text="rapid steer")
|
||||
sk = build_session_key(event.source)
|
||||
runner.adapters[event.source.platform] = adapter
|
||||
|
||||
agent = MagicMock()
|
||||
agent.steer = MagicMock(return_value=True)
|
||||
runner._running_agents[sk] = agent
|
||||
runner._busy_ack_ts[sk] = time.time()
|
||||
|
||||
result = await runner._handle_active_session_busy_message(event, sk)
|
||||
|
||||
assert result is True
|
||||
agent.steer.assert_called_once_with("rapid steer")
|
||||
adapter._send_with_retry.assert_not_called()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_steer_mode_falls_back_to_queue_when_agent_rejects(self):
|
||||
"""If agent.steer() returns False, fall back to queue behavior."""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue