Problem
RemoteConversation.create() registers its conversation ID on the RemoteWorkspace, so the workspace completion callback links the automation run to the created conversation. RemoteConversation.attach() does not register the attached ID. Automations that resume a stable conversation therefore complete successfully but leave automation_runs.conversation_id empty, making the run difficult to trace in Agent Canvas.
Acceptance criteria
RemoteConversation.attach() registers the successfully attached conversation with its workspace.
- The workspace completion callback includes the attached conversation ID, matching create behavior.
- A failed attach does not register an ID.
- Focused tests cover successful and failed attach behavior without changing conversation lifecycle semantics.
OpenHands AI triage
The following comments and acceptance criteria were added by the OpenHands AI agent.
Triage
The report is accurate against main: RemoteConversation.create() calls workspace.register_conversation(info["id"]) (remote_conversation.py), while RemoteConversation.attach() only performs a GET and returns via _from_info, so the attached ID is never registered and OpenHandsCloudWorkspace._send_completion_callback() omits conversation_id. This is the documented register_conversation() contract ("Called by RemoteConversation after creation to associate the conversation with the workspace"), and the shared __init__(conversation_id=...) attach path calls register_conversation only inside its create branch, so every attach route (classmethod or constructor) is affected. The fix belongs in attach() in openhands-sdk/openhands/sdk/conversation/impl/remote_conversation.py, after the GET succeeds, mirroring create(); the callback payload change itself requires no code change. Scope is limited to linking the attached conversation in the automation callback.
Non-goals: no change to create() behavior, to the completion callback payload schema, or to other workspace/conversation entry points such as fork() or navigate_to(); no change to conversation lifecycle, secrets, or transport semantics.
Acceptance Criteria
Problem
RemoteConversation.create()registers its conversation ID on theRemoteWorkspace, so the workspace completion callback links the automation run to the created conversation.RemoteConversation.attach()does not register the attached ID. Automations that resume a stable conversation therefore complete successfully but leaveautomation_runs.conversation_idempty, making the run difficult to trace in Agent Canvas.Acceptance criteria
RemoteConversation.attach()registers the successfully attached conversation with its workspace.OpenHands AI triage
The following comments and acceptance criteria were added by the OpenHands AI agent.
Triage
The report is accurate against
main:RemoteConversation.create()callsworkspace.register_conversation(info["id"])(remote_conversation.py), whileRemoteConversation.attach()only performs aGETand returns via_from_info, so the attached ID is never registered andOpenHandsCloudWorkspace._send_completion_callback()omitsconversation_id. This is the documentedregister_conversation()contract ("Called by RemoteConversation after creation to associate the conversation with the workspace"), and the shared__init__(conversation_id=...)attach path callsregister_conversationonly inside its create branch, so every attach route (classmethod or constructor) is affected. The fix belongs inattach()inopenhands-sdk/openhands/sdk/conversation/impl/remote_conversation.py, after theGETsucceeds, mirroringcreate(); the callback payload change itself requires no code change. Scope is limited to linking the attached conversation in the automation callback.Non-goals: no change to
create()behavior, to the completion callback payload schema, or to other workspace/conversation entry points such asfork()ornavigate_to(); no change to conversation lifecycle, secrets, or transport semantics.Acceptance Criteria
RemoteConversation.attach(workspace, conversation_id),workspace.conversation_idequals the string form of the attached conversation ID, matching the post-create()behavior.AUTOMATION_CALLBACK_URLis set, exiting the workspace context after a successful attach posts a completion callback whose JSON payloadconversation_idequals the attached conversation ID.workspace.conversation_idunchanged — stillNonewhen no ID was previously registered, and still the previously registered value otherwise.RemoteConversation.attach()continues to issue only aGET /api/conversations/{conversation_id}request (no create or update request), so lifecycle semantics are unchanged.tests/sdk/conversation/remote/test_remote_conversation.pycover successful attach registering the ID and failed attach not registering it;tests/workspace/test_cloud_workspace.pycontinues to cover that the callback includesconversation_idwhen registered.