mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-05-06 01:32:36 +00:00
fix: preserve crew name in events, fallback to class name
This commit is contained in:
@@ -213,7 +213,7 @@ class Crew(FlowTrackable, BaseModel):
|
||||
)
|
||||
_kickoff_event_id: str | None = PrivateAttr(default=None)
|
||||
|
||||
name: str | None = Field(default="crew")
|
||||
name: str | None = Field(default=None)
|
||||
cache: bool = Field(default=True)
|
||||
tasks: list[Task] = Field(default_factory=list)
|
||||
agents: Annotated[
|
||||
@@ -853,7 +853,7 @@ class Crew(FlowTrackable, BaseModel):
|
||||
crewai_event_bus.emit(
|
||||
self,
|
||||
CrewTrainStartedEvent(
|
||||
crew_name=self.name,
|
||||
crew_name=self.name or self.__class__.__name__,
|
||||
n_iterations=n_iterations,
|
||||
filename=filename,
|
||||
inputs=inputs,
|
||||
@@ -881,7 +881,7 @@ class Crew(FlowTrackable, BaseModel):
|
||||
crewai_event_bus.emit(
|
||||
self,
|
||||
CrewTrainCompletedEvent(
|
||||
crew_name=self.name,
|
||||
crew_name=self.name or self.__class__.__name__,
|
||||
n_iterations=n_iterations,
|
||||
filename=filename,
|
||||
),
|
||||
@@ -889,7 +889,10 @@ class Crew(FlowTrackable, BaseModel):
|
||||
except Exception as e:
|
||||
crewai_event_bus.emit(
|
||||
self,
|
||||
CrewTrainFailedEvent(error=str(e), crew_name=self.name),
|
||||
CrewTrainFailedEvent(
|
||||
error=str(e),
|
||||
crew_name=self.name or self.__class__.__name__,
|
||||
),
|
||||
)
|
||||
self._logger.log("error", f"Training failed: {e}", color="red")
|
||||
CrewTrainingHandler(TRAINING_DATA_FILE).clear()
|
||||
@@ -974,7 +977,7 @@ class Crew(FlowTrackable, BaseModel):
|
||||
self,
|
||||
CrewKickoffFailedEvent(
|
||||
error=str(e),
|
||||
crew_name=self.name,
|
||||
crew_name=self.name or self.__class__.__name__,
|
||||
started_event_id=self._kickoff_event_id,
|
||||
),
|
||||
)
|
||||
@@ -1185,7 +1188,7 @@ class Crew(FlowTrackable, BaseModel):
|
||||
self,
|
||||
CrewKickoffFailedEvent(
|
||||
error=str(e),
|
||||
crew_name=self.name,
|
||||
crew_name=self.name or self.__class__.__name__,
|
||||
started_event_id=self._kickoff_event_id,
|
||||
),
|
||||
)
|
||||
@@ -1791,7 +1794,7 @@ class Crew(FlowTrackable, BaseModel):
|
||||
crewai_event_bus.emit(
|
||||
self,
|
||||
CrewKickoffCompletedEvent(
|
||||
crew_name=self.name,
|
||||
crew_name=self.name or self.__class__.__name__,
|
||||
output=final_task_output,
|
||||
total_tokens=self.token_usage.total_tokens,
|
||||
started_event_id=self._kickoff_event_id,
|
||||
@@ -2053,7 +2056,7 @@ class Crew(FlowTrackable, BaseModel):
|
||||
crewai_event_bus.emit(
|
||||
self,
|
||||
CrewTestStartedEvent(
|
||||
crew_name=self.name,
|
||||
crew_name=self.name or self.__class__.__name__,
|
||||
n_iterations=n_iterations,
|
||||
eval_llm=llm_instance,
|
||||
inputs=inputs,
|
||||
@@ -2072,13 +2075,16 @@ class Crew(FlowTrackable, BaseModel):
|
||||
crewai_event_bus.emit(
|
||||
self,
|
||||
CrewTestCompletedEvent(
|
||||
crew_name=self.name,
|
||||
crew_name=self.name or self.__class__.__name__,
|
||||
),
|
||||
)
|
||||
except Exception as e:
|
||||
crewai_event_bus.emit(
|
||||
self,
|
||||
CrewTestFailedEvent(error=str(e), crew_name=self.name),
|
||||
CrewTestFailedEvent(
|
||||
error=str(e),
|
||||
crew_name=self.name or self.__class__.__name__,
|
||||
),
|
||||
)
|
||||
raise
|
||||
|
||||
|
||||
@@ -311,7 +311,7 @@ def prepare_kickoff(
|
||||
fmt = ConsoleFormatter(verbose=True)
|
||||
content = fmt.create_status_content(
|
||||
"Resuming from Checkpoint",
|
||||
crew.name or "Crew",
|
||||
crew.name or crew.__class__.__name__,
|
||||
"bright_magenta",
|
||||
ID=str(crew.id),
|
||||
)
|
||||
@@ -319,7 +319,10 @@ def prepare_kickoff(
|
||||
content, "\U0001f504 Resuming from Checkpoint", "bright_magenta"
|
||||
)
|
||||
else:
|
||||
started_event = CrewKickoffStartedEvent(crew_name=crew.name, inputs=normalized)
|
||||
started_event = CrewKickoffStartedEvent(
|
||||
crew_name=crew.name or crew.__class__.__name__,
|
||||
inputs=normalized,
|
||||
)
|
||||
crew._kickoff_event_id = started_event.event_id
|
||||
future = crewai_event_bus.emit(crew, started_event)
|
||||
if future is not None:
|
||||
|
||||
@@ -238,6 +238,9 @@ def crew(
|
||||
|
||||
crew_instance: Crew = _call_method(meth, self, *args, **kwargs)
|
||||
|
||||
if crew_instance.name is None:
|
||||
crew_instance.name = getattr(self, "_crew_name", None)
|
||||
|
||||
def callback_wrapper(
|
||||
hook: Callable[Concatenate[CrewInstance, P2], R2], instance: CrewInstance
|
||||
) -> Callable[P2, R2]:
|
||||
|
||||
@@ -213,7 +213,7 @@ class CrewEvaluator:
|
||||
quality=quality_score,
|
||||
execution_duration=current_task.execution_duration,
|
||||
model=getattr(self.llm, "model", str(self.llm)),
|
||||
crew_name=self.crew.name,
|
||||
crew_name=self.crew.name or self.crew.__class__.__name__,
|
||||
crew=self.crew,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -17,6 +17,7 @@ from crewai.crew import Crew
|
||||
from crewai.crews.crew_output import CrewOutput
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.crew_events import (
|
||||
CrewKickoffStartedEvent,
|
||||
CrewTestCompletedEvent,
|
||||
CrewTestStartedEvent,
|
||||
CrewTrainCompletedEvent,
|
||||
@@ -4738,7 +4739,60 @@ def test_default_crew_name(researcher, writer):
|
||||
Task(description="Task 2", expected_output="output", agent=writer),
|
||||
],
|
||||
)
|
||||
assert crew.name == "crew"
|
||||
assert crew.name is None
|
||||
|
||||
|
||||
def test_crew_kickoff_started_uses_class_name_fallback(researcher, writer):
|
||||
"""Unnamed Crew subclasses should emit their class name in CrewKickoffStartedEvent."""
|
||||
from crewai.crews.utils import prepare_kickoff
|
||||
|
||||
class ResearchAutomation(Crew):
|
||||
pass
|
||||
|
||||
crew = ResearchAutomation(
|
||||
agents=[researcher, writer],
|
||||
tasks=[
|
||||
Task(description="Task 1", expected_output="output", agent=researcher),
|
||||
],
|
||||
)
|
||||
|
||||
captured: list[str | None] = []
|
||||
with crewai_event_bus.scoped_handlers():
|
||||
|
||||
@crewai_event_bus.on(CrewKickoffStartedEvent)
|
||||
def _capture(_source: Any, event: CrewKickoffStartedEvent) -> None:
|
||||
captured.append(event.crew_name)
|
||||
|
||||
prepare_kickoff(crew, inputs=None)
|
||||
|
||||
assert captured == ["ResearchAutomation"]
|
||||
|
||||
|
||||
def test_crew_kickoff_started_respects_explicit_name(researcher, writer):
|
||||
"""Explicitly-named crews should emit the provided name, not the class name."""
|
||||
from crewai.crews.utils import prepare_kickoff
|
||||
|
||||
class ResearchAutomation(Crew):
|
||||
pass
|
||||
|
||||
crew = ResearchAutomation(
|
||||
name="My Research Automation",
|
||||
agents=[researcher, writer],
|
||||
tasks=[
|
||||
Task(description="Task 1", expected_output="output", agent=researcher),
|
||||
],
|
||||
)
|
||||
|
||||
captured: list[str | None] = []
|
||||
with crewai_event_bus.scoped_handlers():
|
||||
|
||||
@crewai_event_bus.on(CrewKickoffStartedEvent)
|
||||
def _capture(_source: Any, event: CrewKickoffStartedEvent) -> None:
|
||||
captured.append(event.crew_name)
|
||||
|
||||
prepare_kickoff(crew, inputs=None)
|
||||
|
||||
assert captured == ["My Research Automation"]
|
||||
|
||||
|
||||
@pytest.mark.vcr()
|
||||
|
||||
@@ -261,6 +261,12 @@ def test_crew_name():
|
||||
assert crew._crew_name == "InternalCrew"
|
||||
|
||||
|
||||
def test_crew_decorator_propagates_class_name_to_instance():
|
||||
"""@crew-decorated factory method should set Crew.name to the decorated class name."""
|
||||
crew_instance = InternalCrew().crew()
|
||||
assert crew_instance.name == "InternalCrew"
|
||||
|
||||
|
||||
@tool
|
||||
def simple_tool():
|
||||
"""Return 'Hi!'"""
|
||||
|
||||
@@ -304,7 +304,7 @@ class TestTraceListenerSetup:
|
||||
# Verify the first completion event has proper structure
|
||||
completion_event = completion_events[0]
|
||||
assert "crew_name" in completion_event.event_data
|
||||
assert completion_event.event_data["crew_name"] == "crew"
|
||||
assert completion_event.event_data["crew_name"] == "Crew"
|
||||
|
||||
# Verify all events have proper structure
|
||||
for call in add_event_mock.call_args_list:
|
||||
|
||||
Reference in New Issue
Block a user