Auto entity deserialization - #544
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request adds a pre-validation step to the Activity model so that well-known entity payloads (e.g., Mention, ProductInfo, Place, etc.) are deserialized into their concrete Entity subclasses during Activity instantiation, while unknown entity shapes continue to deserialize as the base Entity.
Changes:
- Added a new
entity/_validate_known_entities.pymodule that maps knowntypevalues to concreteEntitysubclasses and performs deserialization. - Added a
@field_validator(..., mode="before")onActivity.entitiesto invoke the new validator during model construction.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| libraries/microsoft-agents-activity/microsoft_agents/activity/entity/_validate_known_entities.py | Introduces known-entity type mapping and a pre-validation deserializer (including AI entity detection). |
| libraries/microsoft-agents-activity/microsoft_agents/activity/activity.py | Hooks entity pre-validation into Activity.entities via a Pydantic field_validator. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (6)
libraries/microsoft-agents-activity/microsoft_agents/activity/entity/init.py:42
_validate_known_entitiesis included in__all__, which makes it part of the public export surface despite its leading underscore. If it is meant to remain internal, remove it from__all__(or rename it to a non-underscored public helper and document it).
"_validate_known_entities",
libraries/microsoft-agents-activity/microsoft_agents/activity/entity/init.py:22
_validate_known_entitiesis imported into the publicmicrosoft_agents.activity.entitypackage namespace even though it is prefixed with_(private-by-convention). This unintentionally expands the public API surface; if it is intended to be internal toActivityvalidation, it should not be exported here.
This issue also appears on line 42 of the same file.
from ._validate_known_entities import _validate_known_entities
libraries/microsoft-agents-activity/microsoft_agents/activity/entity/_validate_known_entities.py:50
- The docstring uses
:entities:instead of the Sphinx-style:param entities:used elsewhere in the codebase, and the:returns:line is missing a trailing period. This makes the generated documentation inconsistent and may break doc tooling.
"""Deserialize known activity entities while preserving unknown entity types.
:entities: The data to validate and deserialize into known entity types.
:returns: A list of validated entities, with known types deserialized into their respective classes
:raises ValueError: If the input is not a list or tuple, or if an entity is not a dict or Entity instance.
libraries/microsoft-agents-activity/microsoft_agents/activity/activity.py:206
- The validator always returns a
list[Entity], but the method is annotated as returningAny. Tightening the return type helps static typing and keeps the intent of the validator clear.
def _deserialize_known_entities(cls, entities: Any) -> Any:
return _validate_known_entities(entities)
changelog.md:16
- This changelog line has a trailing space at the end, which can cause noisy diffs and markdown linting issues. Remove the trailing whitespace.
- In the construction of the inbound `Activity` instance, raw `Entity` JSON is automatically deserialized into known derived `Entity` classes such as `ProductInfo`, `Mention`, `AIEntity`, and more.
libraries/microsoft-agents-activity/microsoft_agents/activity/entity/entity_types.py:12
EntityTypes.AI_CITATIONmaps to the schema.org Message URL and is used to deserialize intoAIEntity("Entity indicating AI-generated content"). The constant name reads like it represents a citation rather than the AI content entity itself, which may confuse API consumers scanning the enum.
ACTIVITY_TREATMENT = "activityTreatment"
AI_CITATION = "https://schema.org/Message"
GEO_COORDINATES = "GeoCoordinates"
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (3)
libraries/microsoft-agents-activity/microsoft_agents/activity/entity/init.py:43
__all__exports_validate_known_entities, which makes this underscored helper look like a supported public API. Either remove it from__all__(keep it internal) or rename it to a non-underscored public name if you intend it to be supported.
"ActivityTreatment",
"ActivityTreatmentTypes",
"_validate_known_entities",
]
libraries/microsoft-agents-activity/microsoft_agents/activity/entity/init.py:23
_validate_known_entitiesis a private helper (leading underscore) but this file imports it at package import time, which implicitly promotes it as part of themicrosoft_agents.activity.entitysurface area and can create accidental API dependencies. If this helper is only used internally, avoid importing it fromentity/__init__.pyand keep it module-private.
This issue also appears on line 40 of the same file.
from .stream_info import StreamInfo
from .thing import Thing
from ._validate_known_entities import _validate_known_entities
libraries/microsoft-agents-activity/microsoft_agents/activity/entity/entity_types.py:13
- The new enum member name
AI_CITATIONis misleading: the valuehttps://schema.org/Messagemaps toAIEntity(AI-generated content message), while "citation" is a different concept in this module (e.g.,ClientCitation). Consider renaming this enum member to something that reflects the actual entity type (e.g.,AI_ENTITYorSCHEMA_MESSAGE) to avoid confusion for consumers.
ACTIVITY_TREATMENT = "activityTreatment"
AI_CITATION = "https://schema.org/Message"
GEO_COORDINATES = "GeoCoordinates"
MENTION = "mention"
This pull request introduces a new validation and deserialization mechanism for known entity types in the
Activitymodel, improving how entities are handled during model instantiation. The changes primarily add a custom validator that recognizes and properly deserializes specific entity types, while preserving unknown types, and refactor related code into a new module for clarity and maintainability.Entity deserialization improvements:
_validate_known_entities.py, which defines a mapping of known entity types to their canonical names and classes, and implements the_validate_known_entitiesfunction to deserialize known entities while preserving unknown ones.@field_validatoron theentitiesfield in theActivityclass to automatically invoke_validate_known_entitiesduring deserialization, ensuring that known entity types are properly instantiated._validate_known_entitiesfunction intoactivity.pyfor use in the validator.field_validatorimport frompydanticto support the new validation logic.