Skip to content

Metadata stripping mutates the original computer-task conversation #134

Description

@sylvesterkaczmarek

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions