|
5 | 5 |
|
6 | 6 | import uuid |
7 | 7 | from datetime import datetime, timezone |
8 | | -from typing import TYPE_CHECKING, Annotated, Any, Literal, Optional |
| 8 | +from typing import TYPE_CHECKING, Any, Literal, Optional |
9 | 9 | from uuid import uuid4 |
10 | 10 |
|
11 | 11 | from pydantic import ( |
12 | 12 | AwareDatetime, |
13 | 13 | BaseModel, |
14 | | - BeforeValidator, |
15 | 14 | ConfigDict, |
16 | 15 | Field, |
17 | | - PlainSerializer, |
18 | 16 | model_validator, |
19 | 17 | ) |
20 | 18 |
|
21 | 19 | from pyrit.common.deprecation import print_deprecation_message |
22 | 20 | from pyrit.models.data_type_serializer import data_serializer_factory |
23 | | -from pyrit.models.identifiers.component_identifier import ComponentIdentifier |
24 | 21 | from pyrit.models.literals import ( # noqa: TC001 (runtime-required by Pydantic field annotations) |
25 | 22 | ChatMessageRole, |
26 | 23 | PromptDataType, |
27 | 24 | PromptResponseError, |
28 | 25 | ) |
29 | | -from pyrit.models.score import Score |
| 26 | +from pyrit.models.score import ( # noqa: TC001 (runtime-required by Pydantic field annotations) |
| 27 | + ComponentIdentifierField, |
| 28 | + Score, |
| 29 | +) |
30 | 30 |
|
31 | 31 | if TYPE_CHECKING: |
32 | 32 | from pyrit.models.messages.message import Message |
|
48 | 48 | ) |
49 | 49 |
|
50 | 50 |
|
51 | | -# Annotated alias that round-trips identifier fields through the flat dict |
52 | | -# storage shape. ``ComponentIdentifier`` is a Pydantic model with a custom |
53 | | -# flat serializer; ``Score`` is still a plain class needing ``from_dict`` / |
54 | | -# ``to_dict``. Drop the ``Score`` alias once it becomes a Pydantic model. |
55 | | -ComponentIdentifierField = Annotated[ |
56 | | - ComponentIdentifier, |
57 | | - BeforeValidator(lambda v: ComponentIdentifier.model_validate(v) if isinstance(v, dict) else v), |
58 | | - PlainSerializer(lambda v: v.model_dump() if v is not None else None, return_type=Optional[dict]), |
59 | | -] |
60 | | - |
61 | | -ScoreField = Annotated[ |
62 | | - Score, |
63 | | - BeforeValidator(lambda v: Score.from_dict(v) if isinstance(v, dict) else v), |
64 | | - PlainSerializer(lambda v: v.to_dict(), return_type=dict), |
65 | | -] |
| 51 | +# ``ComponentIdentifierField`` (and ``Score``) are imported from ``pyrit.models.score`` |
| 52 | +# above. Both round-trip through the flat dict storage shape via their own Pydantic |
| 53 | +# serializers, so no local annotated aliases are needed here. |
66 | 54 |
|
67 | 55 |
|
68 | 56 | def __getattr__(name: str) -> Any: |
@@ -128,7 +116,7 @@ class MessagePiece(BaseModel): |
128 | 116 | prompt_target_identifier: Optional[ComponentIdentifierField] = None |
129 | 117 | attack_identifier: Optional[ComponentIdentifierField] = None |
130 | 118 | scorer_identifier: Optional[ComponentIdentifierField] = None |
131 | | - scores: list[ScoreField] = Field(default_factory=list) |
| 119 | + scores: list[Score] = Field(default_factory=list) |
132 | 120 |
|
133 | 121 | # When True, the memory layer skips persisting this piece. Used for ephemeral |
134 | 122 | # pieces a scorer creates to score arbitrary content; ``exclude=True`` keeps |
|
0 commit comments