OpenHands / OpenHands/software-agent-sdk
[Bug]: RemoteConversation attach does not restore tool registrations
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.1k
- Forks
- 539
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 137
Description
Bug Description
RemoteConversation.attach() can fetch an existing conversation whose agent uses tool types from an installed tool package, but it cannot deserialize that conversation's persisted or streamed events unless the attaching process happened to import the same tool modules first. The agent server already persists tool_module_qualnames so it can restore those registrations, but ConversationInfo does not return that metadata to an attaching SDK client.
This breaks general service-owned orchestration: a service can create a conversation from an Agent Profile and later attach through the SDK, yet standard TerminalAction, FileEditorAction, and browser events fail with Unknown kind in the attaching process.
Expected Behavior
The agent server should include the conversation's persisted tool-module mapping in ConversationInfo. RemoteConversation.attach() should import those modules before its initial event sync and WebSocket processing, using the same dynamic registration mechanism already used when creating and restoring conversations.
The attaching application remains responsible for installing the Python packages that provide those modules. It should not need to know or import each agent tool itself.
Actual Behavior
Running python reproduce_attach.py with the steps below reaches the attach successfully, but the initial event search and live WebSocket callbacks repeatedly fail validation for tool action and observation kinds that are registered only in the agent-server process.
The attach succeeds, but initial event search and live WebSocket callbacks repeatedly fail validation for tool action and observation kinds that are registered only in the agent-server process.
Steps to Reproduce
- Start an agent server with
openhands-toolsinstalled. - Create and run a conversation using the default OpenHands agent tools.
- In another process that has
openhands-toolsinstalled but has not imported its tool modules, callRemoteConversation.attach(). - Read persisted events or continue the run.
- Observe
Unknown kind 'TerminalAction'(and equivalent file-editor/browser errors).
Acceptance Criteria
-
ConversationInforeturns the persistedtool_module_qualnamesmapping. -
RemoteConversationimports those modules before its initial persisted-event sync and before WebSocket events are processed. - Reattaching from a fresh process can deserialize standard tool action and observation events without application-specific imports.
- A missing optional tool package is reported clearly and does not obscure which module could not be loaded.
- The Python and generated TypeScript schemas remain in parity.
- Focused agent-server and SDK tests cover the metadata round trip and fresh-client attach behavior.
Installation Method
Source checkout with uv.
SDK Version
Current main / 1.47.0 development tree.
Python Version
3.12
Operating System
Linux
Logs and Error Messages
ValidationError: Unknown kind 'TerminalAction' for openhands.sdk.tool.schema.Action
The same failure occurs for TerminalObservation, FileEditorAction, FileEditorObservation, and browser action/observation kinds.
Additional Context
This is a missing reverse path in existing machinery. Conversation creation already sends tool_module_qualnames, and the server persists and imports them when restoring a conversation. Returning and importing the same mapping on attach avoids role-specific imports in orchestration code.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at RemoteConversation.attach() and ConversationInfo, then trace the existing tool_module_qualnames handling used during conversation creation and restoration. Verify the import occurs before initial persisted-event sync and WebSocket processing, and run focused agent-server and SDK tests. Done means fresh-process attach can deserialize standard tool events, missing packages identify the failed module clearly, and Python and generated TypeScript schemas remain in parity.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100