Skip to content

openhands-api skill shares delegated conversations as legacy UI links instead of Agent Canvas #717

Description

@lilagrc

Summary

The openhands-api skill tells agents to share delegated conversations with legacy UI links. When an agent hands work to a sub-agent through POST /api/v1/app-conversations, it reports /conversations/<id>, which opens the legacy UI instead of Agent Canvas (/canvas/conversations/<id>). A user who started in Agent Canvas is sent to a different UI to follow the sub-agent.

Steps to reproduce

  1. In an Agent Canvas conversation, ask the agent to hand a task to a sub-agent ("give this plan to a sub agent").
  2. The agent follows the skill's delegation checklist: it starts the conversation with POST /api/v1/app-conversations, polls the start task until READY, and shares the link the skill describes.
  3. Open the link. It loads the legacy conversation UI, not Agent Canvas.

Details

  • The checklist builds a legacy, Cloud-only link. skills/openhands-api/SKILL.md says to "Share or store the Cloud URL: https://app.all-hands.dev/conversations/<app_conversation_id>". That is the legacy route, and the hardcoded host is wrong for agents on self-hosted Enterprise.
  • The Python example does the same. It builds {base_url}/conversations/<id>.
  • conversation_url is not a UI link. The app-conversation record's conversation_url is the sandbox's agent-server API URL, so agents can't share it either.
  • The server is adding a proper field. fix(conversations): OHE-3432 return an Agent Canvas link in the API enterprise#606 returns conversation_ui_url (<host>/canvas/conversations/<id>) on app conversations.

Impact

Users switch UIs mid-task: they start in Agent Canvas but follow delegated work in the legacy UI. On self-hosted Enterprise the link can point at the wrong server entirely.

Proposed fix

  • Add a client helper that returns the conversation's conversation_ui_url, falling back to <base_url>/canvas/conversations/<id> for servers that don't return it yet.
  • Point the delegation checklist, the cURL flow, the Python example and the skill README at that link, and say explicitly not to share conversation_url.

Related: OpenHands/enterprise#598 (server side) and OpenHands/OpenHands#17846 (the Agent Canvas launch_child_conversation tool). Proposed fix for this repo: #714.


This issue was created by an AI agent (OpenHands) on behalf of @lilagrc.


OpenHands AI triage

The following comments and acceptance criteria were added by the OpenHands AI agent.

Triage

The report is correct and bounded: skills/openhands-api (mirrored into the plugins/openhands bundle via symlink) tells agents to hand users a legacy /conversations/<id> link for delegated Cloud conversations, and hardcodes https://app.all-hands.dev. Agents should instead share the Agent Canvas route /canvas/conversations/<id> on the deployment's own host. The existing open PR #714 already implements exactly this fix in this repo, so the smallest coherent scope is to land that change (helper + doc/example updates), not to add new machinery.

Scope:

  • Add OpenHandsAPI.app_conversation_ui_url(conversation_id) to skills/openhands-api/scripts/openhands_api.py. It returns the conversation record's conversation_ui_url when the app server provides it (fix(conversations): OHE-3432 return an Agent Canvas link in the API enterprise#606), otherwise falls back to <base_url>/canvas/conversations/<id>.
  • Update skills/openhands-api/SKILL.md (delegation checklist item 6, the cURL flow, the minimal Python flow) and skills/openhands-api/README.md to share that link, and state explicitly that conversation_url is the sandbox agent-server API URL and must not be shared as a UI link.
  • Regenerate derived catalogs with npm run build:skills (and any other sync the change requires).

Non-goals:

  • Do not change the local Agent Canvas section: a standalone local Agent Canvas serves the UI at the root, so <LOCAL_AGENT_SERVER_URL>/conversations/<id> stays as written. Only the Cloud app-conversation path moves under /canvas.
  • Do not add the helper to the TypeScript client (scripts/openhands_api.ts); it has no conversation-lookup helper today.
  • Do not touch other skills that build /conversations/<id> links (github-issue-to-pr, gitlab-issue-to-mr, slack-channel-monitor, news-digest, and similar); those are separate follow-up work.
  • Do not implement or depend on the server-side field here; the helper must work before fix(conversations): OHE-3432 return an Agent Canvas link in the API enterprise#606 is deployed, via the fallback.

Acceptance Criteria

  • OpenHandsAPI.app_conversation_ui_url(conversation_id) exists in skills/openhands-api/scripts/openhands_api.py and returns the value of the conversation record's conversation_ui_url when the app server returns that field.
  • When the app server does not return conversation_ui_url (or returns it empty/null), the helper returns <base_url>/canvas/conversations/<conversation_id> using the client's configured base_url (no hardcoded app.all-hands.dev).
  • The delegation checklist in skills/openhands-api/SKILL.md no longer instructs agents to share https://app.all-hands.dev/conversations/<id> and instead points at the helper's Agent Canvas link, and it explicitly says not to share conversation_url as a UI link.
  • The cURL flow and the minimal Python flow in SKILL.md, plus skills/openhands-api/README.md, present the Agent Canvas link (<host>/canvas/conversations/<id>) for delegated conversations and identify conversation_url as the sandbox agent-server API URL.
  • The local Agent Canvas guidance (<LOCAL_AGENT_SERVER_URL>/conversations/<id>) is left unchanged, since standalone local Agent Canvas serves the UI at the root.
  • Unit tests in tests/test_openhands_api_python.py cover both the server-provided conversation_ui_url and the fallback path; they fail before the change and pass after.
  • Derived artifacts stay in sync: python scripts/sync_extensions.py --check and npm run build:skills leave the working tree clean.
  • Live validation on an Agent Canvas deployment: following the updated instructions, opening the shared link for a delegated conversation loads that conversation in Agent Canvas (not the legacy UI), and the link's host matches the deployment that created it.
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:lowready-for-devScoped for contribution; managed by repository readiness checks.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions