Fix AddImageTool injection for multimodal Agent.kickoff (#3936) #4034
+239
−6
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes how
Agent.kickoff/kickoff_asyncbehave whenmultimodal=Trueis set on the agent.Right now, multimodal support (and
AddImageTool) is wired up when an agent runs inside aCrew, but not when you callAgent.kickoff(...)directly. On top of that, tools were being appended toself.tools, so repeated calls could slowly grow the tool list.With this change, multimodal tools like
AddImageToolare also available when callingAgent.kickoff(...)andkickoff_async(...). The tools are built in a method-local list instead of modifyingself.tools, and an existingAddImageToolon the agent is respected instead of being duplicated.Fixes #3936.
Implementation details
The core of the change is a new private helper,
Agent._get_tools_for_run().That helper starts from a shallow copy of
self.tools(if any), then adds platform tools fromself.appsviaget_platform_tools, and MCP tools fromself.mcpsviaget_mcp_tools. Whenmultimodal=True, it either callsget_multimodal_tools()on the agent (if that’s available) or falls back to injecting a singleAddImageTool. A smallsetof tool types is used to avoid adding duplicate multimodal tools (includingAddImageTool).Both
Agent.kickoff(...)andAgent.kickoff_async(...)now call_get_tools_for_run()and pass the resulting list intoLiteAgent, so the sync and async paths stay aligned without duplicating logic. The goal is to keep the change small and easy to review while still cleaning up the behavior.Tests
New tests live in
lib/crewai/tests/agents/test_agent_kickoff_multimodal.py:test_agent_kickoff_multimodal_adds_add_image_tool_onceChecks that a multimodal agent with no tools gets exactly one
AddImageTool, even ifkickoffis called multiple times.test_agent_kickoff_multimodal_does_not_duplicate_existing_add_image_toolCovers the case where the agent already has an
AddImageTooland confirmskickoffdoesn’t add another.test_agent_kickoff_async_multimodal_adds_add_image_tool_onceAsync version of the first test for
kickoff_async.test_agent_kickoff_async_multimodal_does_not_duplicate_existing_add_image_toolAsync version of the second test for
kickoff_async.test_agent_kickoff_does_not_mutate_agent_toolsUses a
_DummyToolplusmultimodal=Trueto confirm thatLiteAgentsees both the dummy tool andAddImageTool, whileagent.toolsstill only contains the original dummy tool afterkickoff.All tests pass with:
Pre-commit also passes on this branch with:
uv run pre-commit run ruff --all-files uv run pre-commit run ruff-format --all-files # mypy errors are known to be outside this change, no files touched in this PRNotes
crewai-toolscode or external providers.crewai.agent.core.Agentand new tests underlib/crewai/tests/agents/.Note
Make
Agent.kickoff/kickoff_asyncbuild per-run tool lists (including multimodal) without mutatingself.toolsand without duplicates; add tests.tools_for_runfromself.toolsplus platform (get_platform_tools) and MCP (get_mcp_tools) tools.multimodal=True, add multimodal tools (e.g.,AddImageTool) once, avoiding duplicate tool types across runs.self.tools; passtools_for_runtoLiteAgent.LiteAgentreceivesid=self.idin both sync and async paths.lib/crewai/tests/agents/test_agent_kickoff_multimodal.py)AddImageToolis injected exactly once forkickoffandkickoff_async.AddImageToolalready present.agent.toolsis not mutated across runs.Written by Cursor Bugbot for commit 9cd9f24. This will update automatically on new commits. Configure here.