From 3c2435030606da5c1c199bfa19d158ab669ffb2d Mon Sep 17 00:00:00 2001 From: Lucas Gomide Date: Mon, 31 Mar 2025 12:27:36 -0300 Subject: [PATCH 1/2] fix: remove logs we don't need to see from UserMemory initializion (#2497) --- src/crewai/crew.py | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/crewai/crew.py b/src/crewai/crew.py index 60f7c5677..b5f3e3ff5 100644 --- a/src/crewai/crew.py +++ b/src/crewai/crew.py @@ -290,25 +290,18 @@ class Crew(BaseModel): else EntityMemory(crew=self, embedder_config=self.embedder) ) if ( - self.memory_config and "user_memory" in self.memory_config and self.memory_config.get('provider') == 'mem0' + self.memory_config + and "user_memory" in self.memory_config + and self.memory_config.get("provider") == "mem0" ): # Check for user_memory in config user_memory_config = self.memory_config["user_memory"] if isinstance( user_memory_config, dict ): # Check if it's a configuration dict - self._user_memory = UserMemory( - crew=self - ) + self._user_memory = UserMemory(crew=self) else: - raise TypeError( - "user_memory must be a configuration dictionary" - ) + raise TypeError("user_memory must be a configuration dictionary") else: - self._logger.log( - "warning", - "User memory initialization failed. For setup instructions, please refer to the memory documentation: https://docs.crewai.com/concepts/memory#integrating-mem0-for-enhanced-user-memory", - color="yellow" - ) self._user_memory = None # No user memory if not in config return self @@ -1159,7 +1152,7 @@ class Crew(BaseModel): def copy(self): """ Creates a deep copy of the Crew instance. - + Returns: Crew: A new instance with copied components """ @@ -1181,7 +1174,6 @@ class Crew(BaseModel): "knowledge", "manager_agent", "manager_llm", - } cloned_agents = [agent.copy() for agent in self.agents] From 63ef3918dd4cac2e949d03300657b9c019c7122d Mon Sep 17 00:00:00 2001 From: Lucas Gomide Date: Tue, 1 Apr 2025 12:45:45 -0300 Subject: [PATCH 2/2] feat: cleanup Pydantic warning (#2507) A several warnings were addressed following by https://docs.pydantic.dev/2.10/migration --- src/crewai/tools/base_tool.py | 15 +++++++-------- src/crewai/utilities/converter.py | 5 +++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/crewai/tools/base_tool.py b/src/crewai/tools/base_tool.py index b3c0f997c..dc69b02a2 100644 --- a/src/crewai/tools/base_tool.py +++ b/src/crewai/tools/base_tool.py @@ -7,29 +7,27 @@ from pydantic import ( BaseModel, ConfigDict, Field, - PydanticDeprecatedSince20, create_model, - validator, + field_validator, ) from pydantic import BaseModel as PydanticBaseModel from crewai.tools.structured_tool import CrewStructuredTool -# Ignore all "PydanticDeprecatedSince20" warnings globally -warnings.filterwarnings("ignore", category=PydanticDeprecatedSince20) - class BaseTool(BaseModel, ABC): class _ArgsSchemaPlaceholder(PydanticBaseModel): pass - model_config = ConfigDict() + model_config = ConfigDict(arbitrary_types_allowed=True) name: str """The unique name of the tool that clearly communicates its purpose.""" description: str """Used to tell the model how/when/why to use the tool.""" - args_schema: Type[PydanticBaseModel] = Field(default_factory=_ArgsSchemaPlaceholder) + args_schema: Type[PydanticBaseModel] = Field( + default_factory=_ArgsSchemaPlaceholder, validate_default=True + ) """The schema for the arguments that the tool accepts.""" description_updated: bool = False """Flag to check if the description has been updated.""" @@ -38,7 +36,8 @@ class BaseTool(BaseModel, ABC): result_as_answer: bool = False """Flag to check if the tool should be the final agent answer.""" - @validator("args_schema", always=True, pre=True) + @field_validator("args_schema", mode="before") + @classmethod def _default_args_schema( cls, v: Type[PydanticBaseModel] ) -> Type[PydanticBaseModel]: diff --git a/src/crewai/utilities/converter.py b/src/crewai/utilities/converter.py index 991185f4a..b16677ace 100644 --- a/src/crewai/utilities/converter.py +++ b/src/crewai/utilities/converter.py @@ -287,8 +287,9 @@ def generate_model_description(model: Type[BaseModel]) -> str: else: return str(field_type) - fields = model.__annotations__ + fields = model.model_fields field_descriptions = [ - f'"{name}": {describe_field(type_)}' for name, type_ in fields.items() + f'"{name}": {describe_field(field.annotation)}' + for name, field in fields.items() ] return "{\n " + ",\n ".join(field_descriptions) + "\n}"