Merge branch 'main' into docs/checkpointing-restructure

This commit is contained in:
Greyson LaLonde
2026-05-23 12:33:41 +08:00
committed by GitHub
5 changed files with 50 additions and 7 deletions

View File

@@ -16,6 +16,7 @@ from pydantic import (
FilePath,
PrivateAttr,
SecretStr,
field_serializer,
model_validator,
)
from typing_extensions import Self, deprecated
@@ -24,6 +25,7 @@ from crewai.a2a.auth.client_schemes import ClientAuthScheme
from crewai.a2a.auth.server_schemes import ServerAuthScheme
from crewai.a2a.extensions.base import ValidatedA2AExtension
from crewai.a2a.types import ProtocolVersion, TransportType, Url
from crewai.utilities.pydantic_schema_utils import serialize_model_class
try:
@@ -399,6 +401,11 @@ class A2AConfig(BaseModel):
default=None,
description="Optional Pydantic model for structured A2A agent responses",
)
@field_serializer("response_model", when_used="json")
def _serialize_response_model(self, value: Any) -> Any:
return serialize_model_class(value)
fail_fast: bool = Field(
default=True,
description="If True, raise error when agent unreachable; if False, skip",
@@ -488,6 +495,11 @@ class A2AClientConfig(BaseModel):
default=None,
description="Optional Pydantic model for structured A2A agent responses",
)
@field_serializer("response_model", when_used="json")
def _serialize_response_model(self, value: Any) -> Any:
return serialize_model_class(value)
fail_fast: bool = Field(
default=True,
description="If True, raise error when agent unreachable; if False, skip",

View File

@@ -23,6 +23,7 @@ from pydantic import (
BaseModel,
Field,
PrivateAttr,
field_serializer,
field_validator,
model_validator,
)
@@ -94,7 +95,10 @@ from crewai.utilities.guardrail import process_guardrail, serialize_guardrail_fo
from crewai.utilities.guardrail_types import GuardrailCallable, GuardrailType
from crewai.utilities.i18n import I18N_DEFAULT
from crewai.utilities.llm_utils import create_llm
from crewai.utilities.pydantic_schema_utils import generate_model_description
from crewai.utilities.pydantic_schema_utils import (
generate_model_description,
serialize_model_class,
)
from crewai.utilities.token_counter_callback import TokenCalcHandler
from crewai.utilities.tool_utils import execute_tool_and_check_finality
from crewai.utilities.types import LLMMessage
@@ -235,6 +239,11 @@ class LiteAgent(FlowTrackable, BaseModel):
response_format: type[BaseModel] | None = Field(
default=None, description="Pydantic model for structured output"
)
@field_serializer("response_format", when_used="json")
def _serialize_response_format(self, value: Any) -> Any:
return serialize_model_class(value)
verbose: bool = Field(
default=False, description="Whether to print execution details"
)

View File

@@ -23,6 +23,7 @@ from pydantic import (
ConfigDict,
Field,
PrivateAttr,
field_serializer,
model_validator,
)
from typing_extensions import TypedDict
@@ -42,6 +43,7 @@ from crewai.events.types.tool_usage_events import (
ToolUsageStartedEvent,
)
from crewai.types.usage_metrics import UsageMetrics
from crewai.utilities.pydantic_schema_utils import serialize_model_class
try:
@@ -159,6 +161,10 @@ class BaseLLM(BaseModel, ABC):
)
additional_params: dict[str, Any] = Field(default_factory=dict)
@field_serializer("response_format", when_used="json", check_fields=False)
def _serialize_response_format(self, value: Any) -> Any:
return serialize_model_class(value)
def __setattr__(self, name: str, value: Any) -> None:
if name in ("stop", "stop_sequences"):
if value is None:

View File

@@ -8,7 +8,6 @@ from inspect import Parameter, signature
import json
import threading
from typing import (
Annotated,
Any,
Generic,
ParamSpec,
@@ -22,10 +21,10 @@ from pydantic import (
ConfigDict,
Field,
GetCoreSchemaHandler,
PlainSerializer,
PrivateAttr,
computed_field,
create_model,
field_serializer,
field_validator,
)
from pydantic_core import CoreSchema, core_schema
@@ -145,15 +144,18 @@ class BaseTool(BaseModel, ABC):
default_factory=list,
description="List of environment variables used by the tool.",
)
args_schema: Annotated[
type[PydanticBaseModel],
PlainSerializer(_serialize_schema, return_type=dict | None, when_used="json"),
] = Field(
args_schema: type[PydanticBaseModel] = Field(
default=_ArgsSchemaPlaceholder,
validate_default=True,
description="The schema for the arguments that the tool accepts.",
)
@field_serializer("args_schema", when_used="json")
def _serialize_args_schema(
self, schema: type[PydanticBaseModel] | None
) -> dict[str, Any] | None:
return _serialize_schema(schema)
description_updated: bool = Field(
default=False, description="Flag to check if the description has been updated."
)

View File

@@ -782,6 +782,20 @@ def _inline_top_level_ref(schema: dict[str, Any]) -> dict[str, Any]:
return schema
def serialize_model_class(value: Any) -> Any:
"""Serialize a ``type[BaseModel]`` field value as its JSON schema.
Args:
value: A ``type[BaseModel]`` subclass, ``None``, or another union member.
Returns:
``value.model_json_schema()`` for model classes, ``value`` otherwise.
"""
if isinstance(value, type) and issubclass(value, BaseModel):
return value.model_json_schema()
return value
def create_model_from_schema( # type: ignore[no-any-unimported]
json_schema: dict[str, Any],
*,