Summary
strip_all_metadata() is intended to create a cleaned conversation for recorder output, but it uses Pydantic's shallow model_copy() and then assigns filtered metadata onto each copied message.
Because the messages are shared objects in a shallow copy, those assignments also mutate the message metadata in the original conversation.
Current behavior
convo = convo.model_copy(
update={"metadata": ...}
)
for msg in convo.messages:
msg.metadata = {...}
model_copy() is shallow unless deep=True, so convo.messages[i] still refers to the same message object as the source conversation.
Impact
Calling the recorder/logging path can remove metadata from the solver's live/final conversation rather than only from the serialized copy. Logging therefore has an unintended side effect on result data and any later consumers of the conversation.
Proposed resolution
Deep-copy the conversation before rewriting message metadata, while keeping the existing metadata allow-list behavior.
Add a regression that strips metadata from a copied conversation and verifies the returned copy is filtered while the original conversation and message metadata remain unchanged.
Summary
strip_all_metadata()is intended to create a cleaned conversation for recorder output, but it uses Pydantic's shallowmodel_copy()and then assigns filtered metadata onto each copied message.Because the messages are shared objects in a shallow copy, those assignments also mutate the message metadata in the original conversation.
Current behavior
model_copy()is shallow unlessdeep=True, soconvo.messages[i]still refers to the same message object as the source conversation.Impact
Calling the recorder/logging path can remove metadata from the solver's live/final conversation rather than only from the serialized copy. Logging therefore has an unintended side effect on result data and any later consumers of the conversation.
Proposed resolution
Deep-copy the conversation before rewriting message metadata, while keeping the existing metadata allow-list behavior.
Add a regression that strips metadata from a copied conversation and verifies the returned copy is filtered while the original conversation and message metadata remain unchanged.