Bug Description
Two related gaps, both pre-existing and surfaced while reviewing #4814:
1. RemoteConversation.fork() silently drops the fork title
The fork endpoint returns ConversationInfo, which has title and tags as separate top-level fields. But the client-side fork() implementation only reads fork_info.get("tags") from the response when constructing the new RemoteConversation — the title field is ignored entirely. So calling conv.fork(title="My Fork") correctly sends the title to the server (which stores it on StoredConversation), but the returned RemoteConversation object has no record of it.
2. test_remote_fork_uses_server_returned_tags mocks an impossible server shape
The test constructs server_tags = {"env": "test", "title": "My Fork"} and places the whole dict inside the mock response's "tags" key — as if the server returns title inside tags. The real server never does this; title and tags are separate fields on ConversationInfo.
Expected Behavior
RemoteConversation.fork(title="My Fork") returns a fork object that reflects the title the server assigned. The mock in test_remote_fork_uses_server_returned_tags matches the real server response shape, with title as a separate top-level field.
Actual Behavior
The title is sent to and stored by the server correctly, but is silently discarded when RemoteConversation is constructed from the response.
The existing test passes despite mocking an impossible server shape. You can observe this by inspecting what the mock returns vs. what ConversationInfo actually looks like:
uv run pytest tests/sdk/conversation/remote/test_remote_fork.py::test_remote_fork_uses_server_returned_tags -v -s
The test passes, but server_tags includes "title" as a tag key — a shape the real server (ConversationInfo in models.py) never emits. The stale comment in remote_conversation.py that says the server response tags "include merged title" documents this incorrect assumption.
Acceptance Criteria
Additional Context
Discovered while reviewing #4814 (fixing tag pollution from LocalConversation.fork(title=...)). The ConversationInfo wire shape is a server-assembled projection of ConversationState + StoredConversation; the title lives in StoredConversation but wasn't making it back to the client because the SDK read only the tags field from ConversationInfo.
Bug Description
Two related gaps, both pre-existing and surfaced while reviewing #4814:
1.
RemoteConversation.fork()silently drops the fork titleThe fork endpoint returns
ConversationInfo, which hastitleandtagsas separate top-level fields. But the client-sidefork()implementation only readsfork_info.get("tags")from the response when constructing the newRemoteConversation— thetitlefield is ignored entirely. So callingconv.fork(title="My Fork")correctly sends the title to the server (which stores it onStoredConversation), but the returnedRemoteConversationobject has no record of it.2.
test_remote_fork_uses_server_returned_tagsmocks an impossible server shapeThe test constructs
server_tags = {"env": "test", "title": "My Fork"}and places the whole dict inside the mock response's"tags"key — as if the server returns title inside tags. The real server never does this;titleandtagsare separate fields onConversationInfo.Expected Behavior
RemoteConversation.fork(title="My Fork")returns a fork object that reflects the title the server assigned. The mock intest_remote_fork_uses_server_returned_tagsmatches the real server response shape, withtitleas a separate top-level field.Actual Behavior
The title is sent to and stored by the server correctly, but is silently discarded when
RemoteConversationis constructed from the response.The existing test passes despite mocking an impossible server shape. You can observe this by inspecting what the mock returns vs. what
ConversationInfoactually looks like:The test passes, but
server_tagsincludes"title"as a tag key — a shape the real server (ConversationInfoinmodels.py) never emits. The stale comment inremote_conversation.pythat says the server response tags "include merged title" documents this incorrect assumption.Acceptance Criteria
RemoteConversation.fork()readstitlefrom the server response and surfaces it on the returned fork objecttest_remote_fork_uses_server_returned_tagsis updated to mock the correct server response shape (titleas a separate top-level field, not insidetags)"which include merged title"inremote_conversation.pyis removed or correctedAdditional Context
Discovered while reviewing #4814 (fixing tag pollution from
LocalConversation.fork(title=...)). TheConversationInfowire shape is a server-assembled projection ofConversationState+StoredConversation; the title lives inStoredConversationbut wasn't making it back to the client because the SDK read only thetagsfield fromConversationInfo.