Skip to content

Commit aab5401

Browse files
rlundeen2Copilot
andcommitted
MAINT: preserve Message.to_dict back-compat fields
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent a6dbaa3 commit aab5401

3 files changed

Lines changed: 26 additions & 11 deletions

File tree

pyrit/models/message.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -285,18 +285,30 @@ def __str__(self) -> str:
285285

286286
def to_dict(self) -> dict[str, object]:
287287
"""
288-
Convert the message to a dictionary representation including all piece details.
288+
Convert the message to a dictionary representation.
289289
290-
Serializes each piece individually via MessagePiece.to_dict(). All message-level
291-
attributes (role, conversation_id, sequence, is_simulated) are derived from the
292-
pieces themselves, so only 'pieces' is included. This is the format expected by
293-
from_dict().
290+
Includes the original top-level fields ('role', 'converted_value', 'conversation_id',
291+
'sequence', 'converted_value_data_type') for backward compatibility, plus a 'pieces'
292+
list containing each MessagePiece.to_dict() — the latter is the source of truth used
293+
by from_dict().
294294
295295
Returns:
296-
dict[str, object]: Dictionary with a single 'pieces' key containing a list
297-
of MessagePiece.to_dict() dicts.
296+
dict[str, object]: Dictionary with 'role', 'converted_value', 'conversation_id',
297+
'sequence', 'converted_value_data_type', and 'pieces' keys.
298298
"""
299+
if len(self.message_pieces) == 1:
300+
converted_value: str | list[str] = self.message_pieces[0].converted_value
301+
converted_value_data_type: str | list[str] = self.message_pieces[0].converted_value_data_type
302+
else:
303+
converted_value = [piece.converted_value for piece in self.message_pieces]
304+
converted_value_data_type = [piece.converted_value_data_type for piece in self.message_pieces]
305+
299306
return {
307+
"role": self.api_role,
308+
"converted_value": converted_value,
309+
"conversation_id": self.conversation_id,
310+
"sequence": self.sequence,
311+
"converted_value_data_type": converted_value_data_type,
300312
"pieces": [piece.to_dict() for piece in self.message_pieces],
301313
}
302314

tests/unit/message_normalizer/test_generic_system_squash_normalizer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ async def test_generic_squash_normalize_to_dicts_async():
6161
assert isinstance(result, list)
6262
assert len(result) == 1
6363
assert isinstance(result[0], dict)
64-
assert set(result[0].keys()) == {"pieces"}
64+
assert result[0]["role"] == "user"
65+
assert "pieces" in result[0]
6566
assert len(result[0]["pieces"]) == 1
66-
assert result[0]["pieces"][0]["role"] == "user"
6767
assert "### Instructions ###" in result[0]["pieces"][0]["converted_value"]
6868
assert "System message" in result[0]["pieces"][0]["converted_value"]
6969
assert "User message" in result[0]["pieces"][0]["converted_value"]

tests/unit/models/test_message.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,12 @@ def test_message_to_dict() -> None:
226226
message = Message.from_prompt(prompt="Hello world", role="user")
227227
result = message.to_dict()
228228

229-
assert set(result.keys()) == {"pieces"}
229+
assert result["role"] == "user"
230+
assert result["converted_value"] == "Hello world"
231+
assert result["converted_value_data_type"] == "text"
232+
assert "conversation_id" in result
233+
assert "sequence" in result
230234
assert len(result["pieces"]) == 1
231-
assert result["pieces"][0]["role"] == "user"
232235
assert result["pieces"][0]["converted_value"] == "Hello world"
233236
assert result["pieces"][0]["converted_value_data_type"] == "text"
234237

0 commit comments

Comments
 (0)