Skip to content

Fix issue #5736: Agent.kickoff() must honor executor_class#5738

Open
devin-ai-integration[bot] wants to merge 1 commit intomainfrom
devin/1778111398-fix-issue-5736-executor-class-consistency
Open

Fix issue #5736: Agent.kickoff() must honor executor_class#5738
devin-ai-integration[bot] wants to merge 1 commit intomainfrom
devin/1778111398-fix-issue-5736-executor-class-consistency

Conversation

@devin-ai-integration
Copy link
Copy Markdown
Contributor

Summary

Fixes #5736.

The two parallel agent-executor implementations — CrewAgentExecutor (legacy, default for Agent.executor_class) and the experimental AgentExecutor — had drifted enough that the Agent class silently routed kickoff() and execute_task() to different executors:

  • Agent.execute_task() instantiated self.executor_class (default CrewAgentExecutor).
  • Agent.kickoff() hard-coded AgentExecutor and ignored executor_class entirely.
  • The reasoning-gate guard if self.executor_class is not AgentExecutor: handle_reasoning(...) coupled feature behavior to literal class identity, so any subclass of either executor that opted into or out of internal planning was handled incorrectly.

This PR replaces both class-identity checks with two ClassVar capability flags on BaseAgentExecutor:

  • supports_internal_planning — whether the executor runs its own planning/replanning loop (and therefore should not have the external handle_reasoning step run before task execution).
  • supports_kickoff — whether the executor implements the Flow-based Agent.kickoff() entry point.

AgentExecutor sets both to True; CrewAgentExecutor leaves both False (defaults from the base class). Agent now consults these flags:

  • The reasoning gate is now if not getattr(self.executor_class, "supports_internal_planning", False): handle_reasoning(...).
  • Agent.kickoff() routes through a new _resolve_kickoff_executor_class() helper. When the configured executor_class advertises supports_kickoff = True, that class is used verbatim. Otherwise — to preserve backwards compatibility for existing default-configured agents — the helper emits a DeprecationWarning and falls back to AgentExecutor. The warning message tells users how to silence it (executor_class=AgentExecutor).

A new test module lib/crewai/tests/agents/test_executor_consistency.py (12 tests) pins down the contract:

  • Capability flags are correctly set on each executor class.
  • Agent.kickoff() honors a kickoff-capable executor_class (including subclasses) without warning.
  • Agent.kickoff() warns and falls back when executor_class does not opt into kickoff (default CrewAgentExecutor).
  • Agent.execute_task() instantiates self.executor_class (regression guard for the existing path).
  • The reasoning gate is driven by the capability flag, not class identity — so a CrewAgentExecutor subclass that opts into internal planning correctly skips handle_reasoning, and an AgentExecutor subclass that opts out correctly runs it.

Review & Testing Checklist for Human

  • Confirm the deprecation-warning text is acceptable; in particular, confirm the wording ("The silent fallback will be removed in a future release.") aligns with the team's deprecation policy and target release.
  • Decide whether Agent.kickoff() should eventually become a hard error when executor_class doesn't advertise supports_kickoff, or whether the deprecation-then-fallback approach is the long-term plan.
  • Sanity-check that no downstream user-facing entry points other than kickoff() / execute_task() rely on the old self.executor_class is not AgentExecutor class-identity check (a repo-wide grep was clean, but a second pair of eyes is worth it).
  • Run the recorded VCR test that exercises Agent.kickoff() with planning enabled to confirm the deprecation warning surfaces in real usage and that planning still produces a sensible plan when callers explicitly opt into executor_class=AgentExecutor.

Notes

  • No changes to public AgentExecutor / CrewAgentExecutor constructor signatures or imports.
  • The new _resolve_kickoff_executor_class() is private; the public surface stays the same.
  • Lint (ruff check, ruff format --check) and mypy --strict pass on all touched source files. The full lib/crewai/tests/agents/ suite (108 tests across both executor paths) passes locally.

Link to Devin session: https://app.devin.ai/sessions/6be040b5f66d4cc797d36b5a7e144d59

The two parallel agent-executor implementations (CrewAgentExecutor and
the experimental AgentExecutor) had drifted enough that the Agent class
silently routed kickoff() and execute_task() to different executors:

  * Agent.execute_task() instantiated self.executor_class (default
    CrewAgentExecutor).
  * Agent.kickoff() hard-coded AgentExecutor, ignoring executor_class.
  * The reasoning-gate guard 'self.executor_class is not AgentExecutor'
    coupled feature behavior to literal class identity, so a subclass of
    either executor that opted into / out of internal planning was
    handled incorrectly.

This patch introduces two ClassVar capability flags on
BaseAgentExecutor:

  * supports_internal_planning - whether the executor runs its own
    planning/replanning loop (and therefore should NOT have the external
    handle_reasoning step run before task execution).
  * supports_kickoff - whether the executor implements the Flow-based
    kickoff entry point.

AgentExecutor sets both to True; CrewAgentExecutor leaves both False.
The Agent class now consults these flags instead of testing class
identity:

  * The reasoning gate is 'not getattr(executor_class,
    supports_internal_planning, False)'.
  * Agent.kickoff() routes through _resolve_kickoff_executor_class()
    which honors executor_class when it advertises supports_kickoff and
    otherwise emits a DeprecationWarning before falling back to
    AgentExecutor for backwards compatibility.

A new test module
lib/crewai/tests/agents/test_executor_consistency.py pins down the
contract.

Co-Authored-By: João <joao@crewai.com>
@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

@github-actions github-actions Bot added the size/L label May 7, 2026
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] Two parallel agent executors (CrewAgentExecutor vs experimental AgentExecutor) cover the same responsibility — pick a winner

0 participants