CrewAI Integration
CrewAIEventListener subclasses CrewAI's BaseEventListener to capture all
crew lifecycle events — crews, agents, tasks, tools, LLM calls, knowledge
retrieval, memory operations, guardrails, and flows — with start/end pairing
and execution_time_ms computation.
Installation
pip install briefcase-ai
pip install crewai>=0.80.0
# or
pip install briefcase-ai[crewai]
Quick Setup with auto()
The simplest way to instrument CrewAI is one line:
import briefcase_ai
briefcase_ai.auto("crewai")
# That's it — all CrewAI crew events are now traced.
Manual Setup
Instantiating CrewAIEventListener automatically registers it with the
global CrewAI event bus via BaseEventListener.__init_subclass__.
from briefcase_ai.integrations.frameworks import CrewAIEventListener
listener = CrewAIEventListener(context_version="v2.1")
Constructor
CrewAIEventListener(
context_version: Optional[str] = None,
async_capture: bool = True,
capture_crews: bool = True,
capture_agents: bool = True,
capture_tasks: bool = True,
capture_tools: bool = True,
capture_llm: bool = True,
capture_knowledge: bool = True,
capture_memory: bool = True,
capture_guardrails: bool = True,
capture_flows: bool = True,
max_input_chars: int = 10000,
max_output_chars: int = 10000,
exporter: Optional[BaseExporter] = None,
)
| Parameter | Default | Description |
|---|---|---|
context_version | None | Version tag added to all decision records |
async_capture | True | Export in a background daemon thread |
capture_crews | True | Capture crew kickoff / test / train events |
capture_agents | True | Capture agent execution events |
capture_tasks | True | Capture task lifecycle events |
capture_tools | True | Capture tool usage events |
capture_llm | True | Capture LLM call events |
capture_knowledge | True | Capture knowledge retrieval events |
capture_memory | True | Capture memory query / save events |
capture_guardrails | True | Capture guardrail evaluation events |
capture_flows | True | Capture flow and method execution events |
max_input_chars | 10000 | Maximum length of captured input strings |
max_output_chars | 10000 | Maximum length of captured output strings |
exporter | None | Per-instance BaseExporter override |
Basic Usage
from crewai import Crew, Agent, Task
from briefcase_ai.integrations.frameworks import CrewAIEventListener
listener = CrewAIEventListener(context_version="v2.1")
researcher = Agent(
role="Research Analyst",
goal="Find comprehensive information on the given topic.",
backstory="You are an expert researcher.",
)
task = Task(
description="Research AI safety regulations in 2026.",
expected_output="A summary of key regulations.",
agent=researcher,
)
crew = Crew(agents=[researcher], tasks=[task])
result = crew.kickoff()
# Inspect captured records
for record in listener.get_records():
print(f"{record['decision_type']}: {record.get('execution_time_ms', 'N/A')}ms")
Record Format
Each record is a Dict[str, Any] with these fields:
{
"decision_id": "uuid-string",
"decision_type": "crew_kickoff", # see table below
"event_key": "crew1",
"started_at": "2026-02-26T10:00:00Z",
"ended_at": "2026-02-26T10:00:05Z",
"execution_time_ms": 5000.0,
"inputs": {"crew_id": "crew1", "name": "MyCrew"},
"outputs": {"output": "result text"},
"context_version": "v2.1", # if set
"error": "..." # only on failure
}
Event Types
decision_type | Captured when | Start/End paired |
|---|---|---|
crew_kickoff | CrewKickoffStarted/Completed/Failed | Yes |
agent_execution | AgentExecutionStarted/Completed/Error | Yes |
task | TaskStarted/Completed/Failed | Yes |
tool_usage | ToolUsageStarted/Finished/Error | Yes |
llm_call | LLMCallStarted/Completed/Failed | Yes |
knowledge_retrieval | KnowledgeRetrievalStarted/Completed | Yes |
knowledge_query | KnowledgeQueryStarted/Completed/Failed | Yes |
knowledge_search_failed | KnowledgeSearchQueryFailed | No |
memory_query | MemoryQueryStarted/Completed/Failed | Yes |
memory_save | MemorySaveStarted/Completed/Failed | Yes |
memory_retrieval | MemoryRetrievalStarted/Completed | Yes |
llm_guardrail | LLMGuardrailStarted/Completed | Yes |
flow | FlowStarted/Finished | Yes |
flow_created | FlowCreatedEvent | No |
flow_plot | FlowPlotEvent | No |
method_execution | MethodExecutionStarted/Finished/Failed | Yes |
Capture Flags
Disable event categories you don't need to reduce overhead:
listener = CrewAIEventListener(
capture_knowledge=False,
capture_memory=False,
capture_flows=False,
)
Export on Crew Completion
When a crew kickoff completes, the record is automatically passed to the
configured BriefcaseConfig.exporter:
from briefcase_ai.config import setup
from briefcase_ai.exporters import OTelExporter
setup(exporter=OTelExporter(endpoint="http://localhost:4317"))
listener = CrewAIEventListener(async_capture=True)
# Run crew — exports fire asynchronously on each completed event
crew.kickoff()
Public API
| Method | Returns | Description |
|---|---|---|
get_records() | List[Dict[str, Any]] | All captured decision records |
clear() | None | Reset all records and inflight state |
decision_count | int | Number of captured records (property) |
setup_listeners(bus) | None | Register handlers on custom event bus |
Advanced: Per-Instance Exporter
Override the global exporter for this listener instance:
from briefcase_ai.exporters import SplunkHECExporter
listener = CrewAIEventListener(
engagement_id="acme",
exporter=SplunkHECExporter(url="https://splunk.example.com:8088", token="your-hec-token"),
)
Troubleshooting
ImportError: crewai is required: Install with pip install crewai>=0.80.0.
The listener raises at instantiation time if the package is absent.
Events not captured: Ensure you instantiate CrewAIEventListener before
creating or running your crew. The auto-registration happens in __init__.
Missing optional event types: Some event classes (KnowledgeRetrievalStartedEvent,
flow events, etc.) were introduced in specific crewai versions. Briefcase
silently skips missing event types — no error is raised.