Skip to content

fix(workspace): link attached conversations in automation callbacks #5279

Description

@neubig

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

  • After a successful RemoteConversation.attach(workspace, conversation_id), workspace.conversation_id equals the string form of the attached conversation ID, matching the post-create() behavior.
  • When AUTOMATION_CALLBACK_URL is set, exiting the workspace context after a successful attach posts a completion callback whose JSON payload conversation_id equals the attached conversation ID.
  • A failed attach (server returns an HTTP error such as 403/404) raises and leaves workspace.conversation_id unchanged — still None when no ID was previously registered, and still the previously registered value otherwise.
  • RemoteConversation.attach() continues to issue only a GET /api/conversations/{conversation_id} request (no create or update request), so lifecycle semantics are unchanged.
  • Focused tests in tests/sdk/conversation/remote/test_remote_conversation.py cover successful attach registering the ID and failed attach not registering it; tests/workspace/test_cloud_workspace.py continues to cover that the callback includes conversation_id when registered.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority:lowFor bugs, affects only non-mainstream cases, or is annoying but with a clear workaround.ready-for-devIssue meets development readiness criteria

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions