Implement CrewAIBaseModel and Update to ConfigDict (#29)

New CrewAIBaseModel:

Base for Agent, Crew, Task.
Includes generated, frozen UUID.
Adds hashing capability
Migrate to ConfigDict:

Replaces class Config with model_config, see this deprecation note .
Benefits:
Adds auditing capability with frozen UUIDs.
This commit is contained in:
Greyson LaLonde
2023-12-30 19:52:04 -05:00
committed by GitHub
parent 469874d858
commit 1f0001b644
5 changed files with 35 additions and 12 deletions

View File

@@ -6,13 +6,14 @@ from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationSummaryMemory from langchain.memory import ConversationSummaryMemory
from langchain.tools.render import render_text_description from langchain.tools.render import render_text_description
from langchain_core.runnables.config import RunnableConfig from langchain_core.runnables.config import RunnableConfig
from pydantic import BaseModel, Field, InstanceOf, model_validator from pydantic import ConfigDict, Field, InstanceOf, model_validator
from crewai.agents import CacheHandler, CrewAgentOutputParser, ToolsHandler from crewai.agents import CacheHandler, CrewAgentOutputParser, ToolsHandler
from crewai.base.model import CrewAIBaseModel
from crewai.prompts import Prompts from crewai.prompts import Prompts
class Agent(BaseModel): class Agent(CrewAIBaseModel):
"""Represents an agent in a system. """Represents an agent in a system.
Each agent has a role, a goal, a backstory, and an optional language model (llm). Each agent has a role, a goal, a backstory, and an optional language model (llm).
@@ -29,9 +30,7 @@ class Agent(BaseModel):
allow_delegation: Whether the agent is allowed to delegate tasks to other agents. allow_delegation: Whether the agent is allowed to delegate tasks to other agents.
""" """
class Config: model_config = ConfigDict(arbitrary_types_allowed=True)
arbitrary_types_allowed = True
role: str = Field(description="Role of the agent") role: str = Field(description="Role of the agent")
goal: str = Field(description="Objective of the agent") goal: str = Field(description="Objective of the agent")
backstory: str = Field(description="Backstory of the agent") backstory: str = Field(description="Backstory of the agent")

0
crewai/base/__init__.py Normal file
View File

24
crewai/base/model.py Normal file
View File

@@ -0,0 +1,24 @@
import uuid
from typing import Optional
from pydantic import UUID4, BaseModel, Field, field_validator
from pydantic_core import PydanticCustomError
class CrewAIBaseModel(BaseModel):
"""Base model with unique identifier."""
__hash__ = object.__hash__
id: UUID4 = Field(
default_factory=uuid.uuid4,
frozen=True,
description="Unique identifier for the object, not set by user.",
)
@field_validator("id", mode="before")
@classmethod
def _deny_user_set_id(cls, v: Optional[UUID4]) -> None:
if v:
raise PydanticCustomError(
"may_not_set_field", "This field is not to be set by the user.", {}
)

View File

@@ -2,7 +2,7 @@ import json
from typing import Any, Dict, List, Optional, Union from typing import Any, Dict, List, Optional, Union
from pydantic import ( from pydantic import (
BaseModel, ConfigDict,
Field, Field,
InstanceOf, InstanceOf,
Json, Json,
@@ -13,17 +13,16 @@ from pydantic_core import PydanticCustomError
from crewai.agent import Agent from crewai.agent import Agent
from crewai.agents import CacheHandler from crewai.agents import CacheHandler
from crewai.base.model import CrewAIBaseModel
from crewai.process import Process from crewai.process import Process
from crewai.task import Task from crewai.task import Task
from crewai.tools.agent_tools import AgentTools from crewai.tools.agent_tools import AgentTools
class Crew(BaseModel): class Crew(CrewAIBaseModel):
"""Class that represents a group of agents, how they should work together and their tasks.""" """Class that represents a group of agents, how they should work together and their tasks."""
class Config: model_config = ConfigDict(arbitrary_types_allowed=True)
arbitrary_types_allowed = True
tasks: List[Task] = Field(description="List of tasks", default_factory=list) tasks: List[Task] = Field(description="List of tasks", default_factory=list)
agents: List[Agent] = Field( agents: List[Agent] = Field(
description="List of agents in this crew.", default_factory=list description="List of agents in this crew.", default_factory=list

View File

@@ -1,11 +1,12 @@
from typing import Any, List, Optional from typing import Any, List, Optional
from pydantic import BaseModel, Field, model_validator from pydantic import Field, model_validator
from crewai.agent import Agent from crewai.agent import Agent
from crewai.base.model import CrewAIBaseModel
class Task(BaseModel): class Task(CrewAIBaseModel):
"""Class that represent a task to be executed.""" """Class that represent a task to be executed."""
description: str = Field(description="Description of the actual task.") description: str = Field(description="Description of the actual task.")