mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-09 08:08:32 +00:00
* feat: agent metaclass, refactor a2a to wrappers * feat: a2a schemas and utils * chore: move agent class, update imports * refactor: organize imports to avoid circularity, add a2a to console * feat: pass response_model through call chain * feat: add standard openapi spec serialization to tools and structured output * feat: a2a events * chore: add a2a to pyproject * docs: minimal base for learn docs * fix: adjust a2a conversation flow, allow llm to decide exit until max_retries * fix: inject agent skills into initial prompt * fix: format agent card as json in prompt * refactor: simplify A2A agent prompt formatting and improve skill display * chore: wide cleanup * chore: cleanup logic, add auth cache, use json for messages in prompt * chore: update docs * fix: doc snippets formatting * feat: optimize A2A agent card fetching and improve error reporting * chore: move imports to top of file * chore: refactor hasattr check * chore: add httpx-auth, update lockfile * feat: create base public api * chore: cleanup modules, add docstrings, types * fix: exclude extra fields in prompt * chore: update docs * tests: update to correct import * chore: lint for ruff, add missing import * fix: tweak openai streaming logic for response model * tests: add reimport for test * tests: add reimport for test * fix: don't set a2a attr if not set * fix: don't set a2a attr if not set * chore: update cassettes * tests: fix tests * fix: use instructor and dont pass response_format for litellm * chore: consolidate event listeners, add typing * fix: address race condition in test, update cassettes * tests: add correct mocks, rerun cassette for json * tests: update cassette * chore: regenerate cassette after new run * fix: make token manager access-safe * fix: make token manager access-safe * merge * chore: update test and cassete for output pydantic * fix: tweak to disallow deadlock * chore: linter * fix: adjust event ordering for threading * fix: use conditional for batch check * tests: tweak for emission * tests: simplify api + event check * fix: ensure non-function calling llms see json formatted string * tests: tweak message comparison * fix: use internal instructor for litellm structure responses --------- Co-authored-by: Mike Plachta <mike@crewai.com>
77 lines
2.4 KiB
Python
77 lines
2.4 KiB
Python
"""Generic metaclass for agent extensions.
|
|
|
|
This metaclass enables extension capabilities for agents by detecting
|
|
extension fields in class annotations and applying appropriate wrappers.
|
|
"""
|
|
|
|
import warnings
|
|
from functools import wraps
|
|
from typing import Any
|
|
|
|
from pydantic import model_validator
|
|
from pydantic._internal._model_construction import ModelMetaclass
|
|
|
|
|
|
class AgentMeta(ModelMetaclass):
|
|
"""Generic metaclass for agent extensions.
|
|
|
|
Detects extension fields (like 'a2a') in class annotations and applies
|
|
the appropriate wrapper logic to enable extension functionality.
|
|
"""
|
|
|
|
def __new__(
|
|
mcs,
|
|
name: str,
|
|
bases: tuple[type, ...],
|
|
namespace: dict[str, Any],
|
|
**kwargs: Any,
|
|
) -> type:
|
|
"""Create a new class with extension support.
|
|
|
|
Args:
|
|
name: The name of the class being created
|
|
bases: Base classes
|
|
namespace: Class namespace dictionary
|
|
**kwargs: Additional keyword arguments
|
|
|
|
Returns:
|
|
The newly created class with extension support if applicable
|
|
"""
|
|
orig_post_init_setup = namespace.get("post_init_setup")
|
|
|
|
if orig_post_init_setup is not None:
|
|
original_func = (
|
|
orig_post_init_setup.wrapped
|
|
if hasattr(orig_post_init_setup, "wrapped")
|
|
else orig_post_init_setup
|
|
)
|
|
|
|
def post_init_setup_with_extensions(self: Any) -> Any:
|
|
"""Wrap post_init_setup to apply extensions after initialization.
|
|
|
|
Args:
|
|
self: The agent instance
|
|
|
|
Returns:
|
|
The agent instance
|
|
"""
|
|
result = original_func(self)
|
|
|
|
a2a_value = getattr(self, "a2a", None)
|
|
if a2a_value is not None:
|
|
from crewai.a2a.wrapper import wrap_agent_with_a2a_instance
|
|
|
|
wrap_agent_with_a2a_instance(self)
|
|
|
|
return result
|
|
|
|
with warnings.catch_warnings():
|
|
warnings.filterwarnings(
|
|
"ignore", message=".*overrides an existing Pydantic.*"
|
|
)
|
|
namespace["post_init_setup"] = model_validator(mode="after")(
|
|
post_init_setup_with_extensions
|
|
)
|
|
|
|
return super().__new__(mcs, name, bases, namespace, **kwargs)
|