Summary
Follow-up to #2041. A sweep found eleven structures that build their Conversation in __init__ and never reset it in run(). A second run() on the same instance therefore serves the previous task's history. Two of them additionally fan self.run across threads sharing that one object, which is a data race rather than just a leak.
The two races
hybrid_hiearchical_peer_swarm.py — conversation built at :121, and :212:
run_concurrently(self.run, tasks, ...)
N threads call self.conversation.add() on one object, and each returns history_output_formatter(self.conversation, ...) — so every caller receives all tasks' messages, not its own.
multi_agent_router.py — conversation built at :185, and :485:
executor.submit(self.route_task, task)
Same shape.
The leaks
Sequential reuse, so no race, but task N sees task N-1's history:
| File |
Conversation built |
Batch entry point |
advisor_swarm.py |
:118 |
:267 batched_run |
llm_council.py |
:318 |
:534 batched_run |
round_robin.py |
:134 |
:322 batched_run |
debate_with_judge.py |
:182 |
:555 batched_run |
auction_swarm.py |
:286 |
:470 batch_run |
council_as_judge.py |
:289 |
repeated run() |
heavy_swarm.py |
:171 |
repeated run() |
planner_worker_swarm.py |
:586 |
repeated run() |
planner_generator_evaluator.py |
:261 |
repeated run() |
Non-Conversation state with the same problem: spreadsheet_swarm.py:91-93 (self.outputs, self.tasks_completed, self.agent_tasks) and hierarchical_structured_communication_framework.py:1168 (conversation_history, evaluation_results, intermediate_outputs).
Fix
Uniform: reset at the top of run()
self.conversation = Conversation(...)
or accept an injected conversation the way planner_worker_swarm.WorkerPool already does (:369).
For the two races, resetting is not sufficient — a shared instance cannot be safely fanned across threads at all. Either give each task its own conversation (the _clone_for_task approach AgentRearrange.batch_run uses, agent_rearrange.py:1032) or serialize.
Already correct
ma_blocks.py:57, deep_discussion.py:39, and multi_agent_debates.py:49/:121 build a fresh Conversation() inside the function, so they are correct by construction. Worth using them as the reference shape.
Found at 3e89f27b (v14.0.2).
Summary
Follow-up to #2041. A sweep found eleven structures that build their
Conversationin__init__and never reset it inrun(). A secondrun()on the same instance therefore serves the previous task's history. Two of them additionally fanself.runacross threads sharing that one object, which is a data race rather than just a leak.The two races
hybrid_hiearchical_peer_swarm.py— conversation built at:121, and:212:N threads call
self.conversation.add()on one object, and each returnshistory_output_formatter(self.conversation, ...)— so every caller receives all tasks' messages, not its own.multi_agent_router.py— conversation built at:185, and:485:Same shape.
The leaks
Sequential reuse, so no race, but task N sees task N-1's history:
advisor_swarm.py:118:267batched_runllm_council.py:318:534batched_runround_robin.py:134:322batched_rundebate_with_judge.py:182:555batched_runauction_swarm.py:286:470batch_runcouncil_as_judge.py:289run()heavy_swarm.py:171run()planner_worker_swarm.py:586run()planner_generator_evaluator.py:261run()Non-
Conversationstate with the same problem:spreadsheet_swarm.py:91-93(self.outputs,self.tasks_completed,self.agent_tasks) andhierarchical_structured_communication_framework.py:1168(conversation_history,evaluation_results,intermediate_outputs).Fix
Uniform: reset at the top of
run()or accept an injected conversation the way
planner_worker_swarm.WorkerPoolalready does (:369).For the two races, resetting is not sufficient — a shared instance cannot be safely fanned across threads at all. Either give each task its own conversation (the
_clone_for_taskapproachAgentRearrange.batch_runuses,agent_rearrange.py:1032) or serialize.Already correct
ma_blocks.py:57,deep_discussion.py:39, andmulti_agent_debates.py:49/:121build a freshConversation()inside the function, so they are correct by construction. Worth using them as the reference shape.Found at
3e89f27b(v14.0.2).