diff --git a/nanobot/cli/commands.py b/nanobot/cli/commands.py index 4248e055..f480a385 100644 --- a/nanobot/cli/commands.py +++ b/nanobot/cli/commands.py @@ -2076,7 +2076,7 @@ def _run_gateway( run_local_trigger_queue( store=trigger_store, submit_turn=getattr(agent, "submit_local_trigger_turn", None), - is_channel_available=lambda name: name in channels.channels, + is_channel_enabled=lambda name: channels.get_channel(name) is not None, ), name="nanobot-local-triggers", ), diff --git a/nanobot/triggers/local_runner.py b/nanobot/triggers/local_runner.py index b0a9e7ee..39f82c1c 100644 --- a/nanobot/triggers/local_runner.py +++ b/nanobot/triggers/local_runner.py @@ -21,7 +21,7 @@ async def run_local_trigger_queue( *, store: LocalTriggerStore, submit_turn: Callable[[InboundMessage], Awaitable[OutboundMessage | None]] | None = None, - is_channel_available: Callable[[str], bool] | None = None, + is_channel_enabled: Callable[[str], bool], poll_interval_s: float = 0.5, batch_size: int = 20, ) -> None: @@ -47,7 +47,7 @@ async def run_local_trigger_queue( store, delivery, submit_turn=submit_turn, - is_channel_available=is_channel_available, + is_channel_enabled=is_channel_enabled, ) store.complete_delivery(delivery) except asyncio.CancelledError as exc: @@ -132,14 +132,14 @@ async def _deliver_delivery( delivery: TriggerDelivery, *, submit_turn: Callable[[InboundMessage], Awaitable[OutboundMessage | None]], - is_channel_available: Callable[[str], bool] | None = None, + is_channel_enabled: Callable[[str], bool], ) -> None: trigger = store.get(delivery.trigger_id) if trigger is None: raise _TerminalDeliveryError("trigger not found") if not trigger.enabled: raise _TerminalDeliveryError("trigger is disabled") - if is_channel_available is not None and not is_channel_available(trigger.channel): + if not is_channel_enabled(trigger.channel): raise _TerminalDeliveryError(f"target channel is not enabled: {trigger.channel}") store.write_delivery_run_record(delivery, trigger=trigger, status="processing") diff --git a/tests/cli/test_commands.py b/tests/cli/test_commands.py index d5d7dfa3..09d02129 100644 --- a/tests/cli/test_commands.py +++ b/tests/cli/test_commands.py @@ -2748,7 +2748,10 @@ def test_gateway_local_trigger_queue_submits_agent_turns( enabled_channels: list[str] = [] def __init__(self, *_args, **_kwargs) -> None: - self.channels: dict[str, object] = {} + return None + + def get_channel(self, name: str) -> object | None: + return object() if name == "websocket" else None async def start_all(self) -> None: await asyncio.Event().wait() @@ -2776,7 +2779,8 @@ def test_gateway_local_trigger_queue_submits_agent_turns( assert kwargs["store"] is agent_kwargs["local_trigger_store"] assert "bus" not in kwargs assert kwargs["submit_turn"] is agent.submit_local_trigger_turn - assert kwargs["is_channel_available"]("websocket") is False + assert kwargs["is_channel_enabled"]("websocket") is True + assert kwargs["is_channel_enabled"]("telegram") is False def test_gateway_workspace_override_does_not_migrate_legacy_cron( diff --git a/tests/triggers/test_local_triggers.py b/tests/triggers/test_local_triggers.py index 79f62768..41fe91d0 100644 --- a/tests/triggers/test_local_triggers.py +++ b/tests/triggers/test_local_triggers.py @@ -17,6 +17,10 @@ from nanobot.triggers.local_types import LocalTrigger, TriggerDelivery from nanobot.webui.metadata import WEBUI_MESSAGE_SOURCE_METADATA_KEY, WEBUI_TURN_METADATA_KEY +def _channel_is_enabled(_name: str) -> bool: + return True + + def _write_delivery_file(path: Path, *, trigger_id: str, delivery_id: str) -> None: path.write_text( json.dumps( @@ -257,7 +261,12 @@ async def test_local_trigger_queue_submits_bound_inbound_message(tmp_path: Path) return OutboundMessage(channel=msg.channel, chat_id=msg.chat_id, content="done") task = asyncio.create_task( - run_local_trigger_queue(store=store, submit_turn=_submit_turn, poll_interval_s=0.01) + run_local_trigger_queue( + store=store, + submit_turn=_submit_turn, + is_channel_enabled=_channel_is_enabled, + poll_interval_s=0.01, + ) ) try: for _ in range(100): @@ -319,7 +328,7 @@ async def test_local_trigger_queue_rejects_unavailable_target_channel(tmp_path: run_local_trigger_queue( store=store, submit_turn=_submit_turn, - is_channel_available=lambda name: name == "websocket", + is_channel_enabled=lambda name: name == "websocket", poll_interval_s=0.01, ) ) @@ -369,6 +378,7 @@ async def test_local_trigger_queue_waits_for_submitted_turn_before_ack( run_local_trigger_queue( store=store, submit_turn=_submit_turn, + is_channel_enabled=_channel_is_enabled, poll_interval_s=0.01, ) ) @@ -428,6 +438,7 @@ async def test_local_trigger_queue_requeues_when_submitted_turn_is_interrupted( run_local_trigger_queue( store=store, submit_turn=_submit_turn, + is_channel_enabled=_channel_is_enabled, poll_interval_s=0.01, ) ) @@ -473,6 +484,7 @@ async def test_local_trigger_queue_does_not_retry_completed_agent_failure( run_local_trigger_queue( store=store, submit_turn=_submit_turn, + is_channel_enabled=_channel_is_enabled, poll_interval_s=0.01, ) ) @@ -521,7 +533,12 @@ async def test_local_trigger_queue_recovers_processing_delivery_on_start( restarted = LocalTriggerStore(tmp_path) task = asyncio.create_task( - run_local_trigger_queue(store=restarted, submit_turn=_submit_turn, poll_interval_s=0.01) + run_local_trigger_queue( + store=restarted, + submit_turn=_submit_turn, + is_channel_enabled=_channel_is_enabled, + poll_interval_s=0.01, + ) ) try: for _ in range(100):