diff --git a/astromesh-adk/CHANGELOG.md b/astromesh-adk/CHANGELOG.md index e19f90f8..5538049e 100644 --- a/astromesh-adk/CHANGELOG.md +++ b/astromesh-adk/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed +- `ADKRuntime._run_swarm` now raises a descriptive `ValueError` (`swarm team '' has no entry_agent and no agents`) when an `AgentTeam` with the `swarm` pattern has neither `entry_agent` nor `agents`, instead of crashing with `IndexError` on `team.agents[0]` (`astromesh_adk/runner.py`) + ## [0.1.9] - 2026-07-10 ### Added diff --git a/astromesh-adk/astromesh_adk/runner.py b/astromesh-adk/astromesh_adk/runner.py index 97d56323..a9c8c0c0 100644 --- a/astromesh-adk/astromesh_adk/runner.py +++ b/astromesh-adk/astromesh_adk/runner.py @@ -438,6 +438,8 @@ async def delegating_tool_fn(name: str, args: dict): ) async def _run_swarm(self, team, query, session_id, context) -> RunResult: + if team.entry_agent is None and not team.agents: + raise ValueError(f"swarm team {team.name!r} has no entry_agent and no agents") agents = {a.name: a for a in team.agents} entry = team.entry_agent or team.agents[0] tctx = TracingContext(entry.name, session_id) diff --git a/astromesh-adk/tests/test_runner_local.py b/astromesh-adk/tests/test_runner_local.py index 830d89b1..ae2e6cb9 100644 --- a/astromesh-adk/tests/test_runner_local.py +++ b/astromesh-adk/tests/test_runner_local.py @@ -318,3 +318,24 @@ async def on_after_run(self, ctx, result): result = await rt.run_class_agent(MyAgent(), "q", "s") assert result.answer == "cls-out" assert calls == ["before", "after"] + + +@pytest.mark.asyncio +async def test_run_team_swarm_returns_entry_answer(): + rt = ADKRuntime(provider_factory=lambda p, m, c: FakeProvider(m, content="swarm-final")) + team = AgentTeam( + name="sw", + pattern="swarm", + agents=[_agent(name="a1", model="claude-x"), _agent(name="a2", model="gpt-y")], + entry_agent=_agent(name="entry", model="claude-x"), + ) + result = await rt.run_team(team, "q", "s") + assert result.answer == "swarm-final" + + +@pytest.mark.asyncio +async def test_run_team_swarm_empty_team_raises_valueerror(): + rt = ADKRuntime(provider_factory=lambda p, m, c: FakeProvider(m)) + team = AgentTeam(name="empty", pattern="swarm", agents=[], entry_agent=None) + with pytest.raises(ValueError, match=r"swarm team 'empty' has no entry_agent and no agents"): + await rt.run_team(team, "q", "s")