Skip to content

fix: prevent shared LLM stop words mutation across agents (#5141)#5142

Open
devin-ai-integration[bot] wants to merge 2 commits intomainfrom
devin/1774620146-fix-shared-llm-stop-words-mutation
Open

fix: prevent shared LLM stop words mutation across agents (#5141)#5142
devin-ai-integration[bot] wants to merge 2 commits intomainfrom
devin/1774620146-fix-shared-llm-stop-words-mutation

Conversation

@devin-ai-integration
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot commented Mar 27, 2026

Summary

Fixes #5141. When multiple agents share the same LLM instance, the executor's __init__ was directly mutating self.llm.stop on the shared object. This caused stop words to accumulate across agents and across repeated crew.kickoff() calls, leading to incorrect LLM behavior.

The fix creates a shallow copy of the LLM via copy.copy() before merging stop words, so each executor gets an isolated stop word list. The copy is only made when new stop words are actually being added (to avoid unnecessary allocations). Applied identically to both CrewAgentExecutor and experimental AgentExecutor.

Review & Testing Checklist for Human

  • Verify copy.copy() is safe on your LLM subclasses — shallow copy shares all internal references (connection pools, caches, provider state). Confirm no LLM subclass relies on identity (is) checks or has mutable internal state that would break when shared between original and copy. This is the highest-risk aspect of this change.
  • Test with a real multi-agent crew — create a crew with 2+ agents sharing one LLM(model=..., stop=["X"]) instance, run kickoff() multiple times, and confirm stop words don't grow on the shared LLM and each agent behaves correctly.
  • Order-sensitive comparison may cause unnecessary copiesmerged_stop is built from set(), so ["A", "B"] could become ["B", "A"]. The != check against existing_stop is order-sensitive, meaning even when no new stop words are added but order differs, a copy is still made. This is harmless but slightly wasteful. Consider using set() comparison instead if this matters.

Notes

  • The or [] addition (getattr(self.llm, "stop", []) or []) is a minor behavioral change that converts an explicit None on stop to []. This is likely correct since downstream code expects a list.
  • 7 new regression tests added across both test files covering: single executor isolation, multi-executor isolation, no-copy optimization, and repeated kickoff accumulation.
  • CI note: the tests (3.10) failure (test_custom_llm_within_crew) is a pre-existing flaky test unrelated to this change. The tests (3.11/3.12/3.13) runs were cancelled (not failed) due to CI infrastructure behavior. Lint, type-checker (all versions), and CodeQL all pass.

Link to Devin session: https://app.devin.ai/sessions/0807fced3a7b4e4ab5cbe3a6a0d7ed2e

When multiple agents share the same LLM instance, the executor was
directly mutating the shared LLM's stop words list. This caused
cross-agent state pollution where stop words would accumulate across
agents and across multiple crew.kickoff() calls.

Fix: create a shallow copy of the LLM before merging stop words,
so each executor gets its own isolated stop word list. Only copy
when new stop words are actually being added to avoid unnecessary
allocations.

Applied to both CrewAgentExecutor and experimental AgentExecutor.

Co-Authored-By: João <[email protected]>
@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

Prompt hidden (unlisted session)

@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Shared LLM stop words mutation causes cross-agent state pollution

0 participants