diff --git a/src/rai_core/rai/agents/runner.py b/src/rai_core/rai/agents/runner.py index 447d18d11..d23967fb8 100644 --- a/src/rai_core/rai/agents/runner.py +++ b/src/rai_core/rai/agents/runner.py @@ -37,6 +37,8 @@ def wait_for_shutdown(agents: List[BaseAgent]): an interrupt signal (SIGINT, e.g., Ctrl+C) or SIGTERM. It installs signal handlers to capture these events and invokes the agent's ``stop()`` method as part of the shutdown process. """ + if not isinstance(agents, list) or len(agents) == 0: + raise ValueError("agents must be a non-empty list of BaseAgent instances") shutdown_event = Event() def signal_handler(signum, frame): @@ -58,6 +60,8 @@ def run_agents(agents: List[BaseAgent]): Args: agents: List of agent instances """ + if not isinstance(agents, list) or len(agents) == 0: + raise ValueError("agents must be a non-empty list of BaseAgent instances") logger.info( "run_agents is an experimental function. \ If you believe that your agents are not running properly, \ @@ -84,6 +88,8 @@ def __init__(self, agents: List[BaseAgent]): agents : List[BaseAgent] List of agent instances to be managed by the runner. """ + if not isinstance(agents, list) or len(agents) == 0: + raise ValueError("agents must be a non-empty list of BaseAgent instances") self.agents = agents self.logger = logging.getLogger(__name__) diff --git a/tests/agents/test_agent_runner_empty.py b/tests/agents/test_agent_runner_empty.py new file mode 100644 index 000000000..4dc06015e --- /dev/null +++ b/tests/agents/test_agent_runner_empty.py @@ -0,0 +1,30 @@ +# Copyright (C) 2025 Robotec.AI +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest +from rai.agents.runner import AgentRunner, run_agents, wait_for_shutdown + + +@pytest.mark.parametrize( + "fn", + [ + lambda: run_agents([]), + lambda: wait_for_shutdown([]), + lambda: AgentRunner([]), + lambda: run_agents(None), # type: ignore[arg-type] + ], +) +def test_agent_helpers_reject_empty_agents(fn): + with pytest.raises(ValueError, match="agents must be a non-empty list"): + fn()