Skip to main content
View source

CrewAI Agent

View as Markdown

Run CrewAI agents inside RocketRide: as a standalone agent, as a hierarchical manager that orchestrates a crew of sub-agents, or as a managed sub-agent worker.

What it does

Three node variants share the same base driver (crewai_base.py), each loaded from its own sub-package:

  • CrewAI Agent (agent_crewai): a standalone single agent. Assembles a CrewAI Agent + Task into a one-agent, sequential-process Crew and runs it to answer the incoming question.
  • CrewAI Manager (agent_crewai_manager): orchestrates a crew using CrewAI's hierarchical process. Fans out a describe invoke to connected CrewAI Subagent nodes, assembles a Crew with the manager as delegator (planning=True, using the manager's LLM as the planning LLM), and synthesizes sub-agent outputs into one answer.
  • CrewAI Subagent (agent_crewai_subagent): a managed worker. Wired into a Manager via the crewai channel and delegated to by name (its role); it has no questions lane and cannot be invoked directly.

Uses the crewai library (>=1.14.1). The node never calls a model provider directly: the wrapped CrewAI BaseLLM and BaseTool instances route every LLM and tool call back through the pipeline's own llm and tool channels, so each agent uses exactly the LLM and tools wired to its own node.

All crew kickoffs are funneled onto one shared asyncio event loop running on a single daemon thread (crewai_runner.py). This is necessary because CrewAI's process-global singletons (event bus, telemetry, console formatter) are not safe under concurrent kickoffs from multiple threads. Concurrent chats still overlap their IO at await points. A persistent event listener (crewai_listener.py) forwards CrewAI bus events (task started, agent thinking, tool calls, LLM calls, and so on) to the originating run as thinking SSE messages, routed per-run via a ContextVar.

CrewAI 1.14.x planning and delegation are patched at import time (crewai_base.py) to run safely inside the shared asyncio loop: planning is offloaded to a worker thread, and delegation tools gain async variants that use aexecute_task(). Without these patches, hierarchical crews raise RuntimeError when they detect a running event loop.


Configuration

Lanes

VariantLanesllm channeltool channelcrewai channel
CrewAI Agentquestions -> answersrequired (min 1)optionaln/a
CrewAI Managerquestions -> answersrequired (min 1)n/arequired (min 1 Subagent)
CrewAI Subagentnonerequired (min 1)optionaln/a

The Agent and Manager are registered as tools too (classType: ["agent", "tool"]) and expose themselves as <nodeId>.run_agent, so a parent agent can delegate to them in hierarchical pipelines. The run_agent tool accepts {query: string, context?: object} and returns {content, meta, stack}. Tools attach through the tool invoke channel (control-plane invoke), not through lanes.

The Subagent's classType is ["crewai"]: it can only be wired into a Manager's crewai channel and cannot be called via run_agent. A CrewAI Agent node cannot be used as a sub-agent under a Manager (its classType does not include crewai), and a Manager cannot be nested under another Manager via the crewai channel. Cross-Manager composition goes through run_agent instead.

A Subagent can be connected to multiple Managers simultaneously: each Manager independently includes it in its own hierarchical Crew, enabling shared specialist sub-agents across delegation hierarchies.

Each variant shows only its description/instructions fields by default. Toggle Advanced Mode (advanced_mode, default false) to expose the CrewAI Agent and Task fields. Blank goal, backstory, and expected_output values fall back to built-in defaults at run time.

CrewAI Agent

FieldTypeDescription
instructionsarrayAdditional instructions to guide this sub-agent when the Manager delegates to it.
advanced_modebooleanDefault false. Expose CrewAI Agent and Task configuration directly.
agent_config_headernull
rolestringSub-agent role name (e.g. 'Financial Analyst'). The Manager uses this name when routing delegation. Maps to CrewAI Agent(role=...).
goalstringWhat this sub-agent aims to achieve when delegated to. Maps to CrewAI Agent(goal=...).
backstorystringBackground context for this sub-agent's expertise. Helps the Manager and the sub-agent's own LLM reason about when it's the right choice. Maps to CrewAI Agent(backstory=...).
task_config_headernull
task_descriptionstringWhat this sub-agent does when delegated to by the Manager. The user's request is passed as additional context at run time. Maps to CrewAI Task(description=...).
expected_outputstringDescription of the expected output format. Maps to CrewAI Task(expected_output=...).
agent_descriptionstringDefault empty. What does this agent do? Describe its purpose and capabilities, this helps parent agents select and invoke it correctly.

CrewAI Manager

FieldType/DefaultDescription
agent_descriptionstring, ""What this manager and its sub-agent crew does. Used by parent agents that call it as a tool via <nodeId>.run_agent.
instructionsarray, []Additional instructions to guide the manager's delegation strategy. Appended to the manager's backstory.
advanced_modeboolean, falseWhen On, exposes the manager Agent config fields below.
goalstring, ""What the manager is trying to achieve. Maps to Agent(goal=...).
backstorystring, ""Background context for the manager's persona. Maps to Agent(backstory=...).

The Manager requires at least one connected CrewAI Subagent on the crewai channel (min 1). It raises an error at run time if no sub-agents are connected or none respond to the describe fan-out.

CrewAI Subagent

FieldType/DefaultDescription
instructionsarray, []Additional instructions for this sub-agent when the Manager delegates to it. Appended to its backstory.
advanced_modeboolean, falseWhen On, exposes the Agent and Task config fields below.
rolestring, "Specialist"Sub-agent role name. The Manager uses this name when routing delegation. Maps to Agent(role=...).
goalstring, ""What this sub-agent aims to achieve. Maps to Agent(goal=...).
backstorystring, ""Background context and expertise. Helps the Manager and the sub-agent's own LLM reason about when it is the right choice. Maps to Agent(backstory=...).
task_descriptionstring, ""What this sub-agent does when delegated to. Supports CrewAI template variables: {user_request} resolves to the raw user prompt; if blank, the task is just {user_request}. Maps to Task(description=...).
expected_outputstring, ""Description of the expected output format. Maps to Task(expected_output=...).

How the Manager works

  1. Fans out a describe invoke to each node on the crewai channel individually. Each Subagent responds with its role, goal, backstory, task description, expected output, instructions, and a handle to its own engine channels.
  2. Builds a CrewAI Agent + Task per descriptor (max_iter=5, allow_delegation=False), routing LLM and tool calls back through that sub-agent's own llm/tool channels. The sub-agents' channels are fully independent of the Manager's.
  3. Builds the manager agent (allow_delegation=True, max_iter=5) from this node's llm channel and config. The user's prompt is placed in the manager's backstory as background context, keeping the goal generic.
  4. Kicks off a Process.hierarchical Crew with planning=True and returns the synthesized result.

Result extraction

In hierarchical mode CrewAI's result.raw often contains the manager's full ReAct trace (delegations and observations) rather than just the answer. The Manager therefore prefers the last completed task's output and strips any ReAct preamble: everything after the last Final Answer: marker, or, when the agent ended on a tool observation, the last complete top-level JSON block. Non-ReAct output is returned as-is.


Observability

Every CrewAI bus event from a kickoff (crew/task/agent lifecycle, tool usage, LLM calls) is forwarded to the originating run's invoker as a thinking SSE message with a human-friendly label (for example, "Agent thinking...", "Calling ..."). LLM stream chunks and CrewAI's terminal-formatter log events are skipped to avoid flooding the UI. Routing is per-run via a ContextVar, so concurrent chats never see each other's events.


Known limitations

  • When the LLM uses native function calling, CrewAI invokes tools synchronously on the shared kickoff loop, so tool calls serialize across concurrent runs in that path. The ReAct tool path (_arun) offloads to a thread and does not block the loop.
  • CrewAI 1.14.x planning and delegation are patched at import time to run safely inside the shared asyncio loop. Without these patches, hierarchical crews raise RuntimeError when they detect a running event loop.

Schema

CrewAI Agent (services.agent.json)

FieldTypeDescriptionDefault
advanced_modebooleanAdvanced Mode
Expose CrewAI Agent and Task configuration directly.
false
agent_crewai.agent_config_headernullAgent Confignull
agent_crewai.task_config_headernullTask Confignull
agent_descriptionstringAgent description
What does this agent do? Describe its purpose and capabilities, this helps parent agents select and invoke it correctly.
""
backstorystringBackstory
Background context for this agent's persona. Maps to CrewAI Agent(backstory=...).
expected_outputstringExpected Output
Description of the expected output format. Maps to CrewAI Task(expected_output=...).
goalstringGoal
What this agent is trying to achieve. Maps to CrewAI Agent(goal=...).
instructionsarrayInstructions
Additional instructions to guide the agent.
rolestringRole
Agent role name (e.g. 'Financial Analyst'). Maps to CrewAI Agent(role=...).
task_descriptionstringTask
What this agent should do. If blank, the incoming question is used. Maps to CrewAI Task(description=...).

CrewAI Manager (services.manager.json)

FieldTypeDescriptionDefault
advanced_modebooleanAdvanced Mode
Expose CrewAI manager Agent configuration directly.
false
agent_descriptionstringAgent description
What this manager + its sub-agent crew does. Used by parent agents that call this manager as a tool via <nodeId>.run_agent to decide when to invoke it.
""
backstorystringManager Backstory
Background context for the manager's persona. Maps to CrewAI Agent(backstory=...).
goalstringManager Goal
What the manager is trying to achieve. Maps to CrewAI Agent(goal=...).
instructionsarrayInstructions
Additional instructions to guide the manager's delegation strategy.

CrewAI Subagent (services.subagent.json)

FieldTypeDescriptionDefault
advanced_modebooleanAdvanced Mode
Expose CrewAI Agent and Task configuration directly.
false
agent_crewai_subagent.agent_config_headernullAgent Confignull
agent_crewai_subagent.task_config_headernullTask Confignull
backstorystringBackstory
Background context for this sub-agent's expertise. Helps the Manager and the sub-agent's own LLM reason about when it's the right choice. Maps to CrewAI Agent(backstory=...).
expected_outputstringExpected Output
Description of the expected output format. Maps to CrewAI Task(expected_output=...).
goalstringGoal
What this sub-agent aims to achieve when delegated to. Maps to CrewAI Agent(goal=...).
instructionsarrayInstructions
Additional instructions to guide this sub-agent when the Manager delegates to it.
rolestringRole
Sub-agent role name (e.g. 'Financial Analyst'). The Manager uses this name when routing delegation. Maps to CrewAI Agent(role=...).
task_descriptionstringTask
What this sub-agent does when delegated to by the Manager. The user's request is passed as additional context at run time. Maps to CrewAI Task(description=...).

Dependencies

  • crewai >=1.14.1