Skip to content

Commit 2c0b1f1

Browse files
committed
[Bug] planning_enabled permanently strips the director's SwarmSpec schema
HierarchicalSwarm.run_director and the async streaming loop both set self.director.tools_list_dictionary = None before running the planning sub-step. That assignment cannot do what it looks like it does. setup_director_with_planning builds its own throwaway Agent and already excludes base_model and tools_list_dictionary from the settings it forwards, so planning has always run schema-free without any help. The line only reaches the real director -- the one the swarm depends on for structured SwarmSpec output on the very next call, and the one the caller may own when a director is passed in explicitly. Delete both assignments. Add a test that pins the director's schema across a planning-enabled run_director.
1 parent fd9c2e0 commit 2c0b1f1

2 files changed

Lines changed: 36 additions & 2 deletions

File tree

swarms/structs/hiearchical_swarm.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,6 @@ def run_director(
762762
"""
763763
try:
764764
if self.planning_enabled is True:
765-
self.director.tools_list_dictionary = None
766765
out = self.setup_director_with_planning(
767766
task=f"History: {self.conversation.get_str()} \n\n Task: {task}",
768767
img=img,
@@ -2000,7 +1999,6 @@ async def arun_stream(
20001999
# Optional planning sub-step (non-streaming — creates a
20012000
# throwaway agent with modified tools)
20022001
if self.planning_enabled:
2003-
self.director.tools_list_dictionary = None
20042002
plan_out = await asyncio.to_thread(
20052003
self.setup_director_with_planning,
20062004
task=director_task_str,

tests/structs/test_hierarchical_swarm.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,5 +1056,41 @@ def test_reassignment_targets_nested_swarm_worker_by_name():
10561056
assert "[RECOVERY NOTICE]" not in swarm.conversation.get_str()
10571057

10581058

1059+
def test_planning_keeps_the_director_tool_schema(monkeypatch):
1060+
"""The planning sub-step must not disarm the real director.
1061+
1062+
setup_director_with_planning builds its own throwaway agent, so
1063+
clearing the director's tools_list_dictionary bought nothing and
1064+
cost the SwarmSpec schema the very next call depends on.
1065+
"""
1066+
schema = [{"type": "function", "function": {"name": "SwarmSpec"}}]
1067+
director = StubAgent(
1068+
"Director",
1069+
[
1070+
{
1071+
"plan": "Hand the task to the worker.",
1072+
"orders": [
1073+
{"agent_name": "Worker", "task": "do the thing"}
1074+
],
1075+
}
1076+
],
1077+
)
1078+
director.tools_list_dictionary = schema
1079+
1080+
swarm = make_recovery_swarm(
1081+
director, [StubAgent("Worker", ["done"])]
1082+
)
1083+
swarm.planning_enabled = True
1084+
monkeypatch.setattr(
1085+
swarm,
1086+
"setup_director_with_planning",
1087+
lambda task, img=None: "a plan",
1088+
)
1089+
1090+
swarm.run_director(task="ship it")
1091+
1092+
assert director.tools_list_dictionary == schema
1093+
1094+
10591095
if __name__ == "__main__":
10601096
pytest.main([__file__, "-v"])

0 commit comments

Comments
 (0)