You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
openhands-api skill shares delegated conversations as legacy UI links instead of Agent Canvas #717
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
In an Agent Canvas conversation, ask the agent to hand a task to a sub-agent ("give this plan to a sub agent").
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.
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.
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.
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.
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.
Summary
The
openhands-apiskill tells agents to share delegated conversations with legacy UI links. When an agent hands work to a sub-agent throughPOST /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
POST /api/v1/app-conversations, polls the start task untilREADY, and shares the link the skill describes.Details
skills/openhands-api/SKILL.mdsays 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.{base_url}/conversations/<id>.conversation_urlis not a UI link. The app-conversation record'sconversation_urlis the sandbox's agent-server API URL, so agents can't share it either.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
conversation_ui_url, falling back to<base_url>/canvas/conversations/<id>for servers that don't return it yet.conversation_url.Related: OpenHands/enterprise#598 (server side) and OpenHands/OpenHands#17846 (the Agent Canvas
launch_child_conversationtool). 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 theplugins/openhandsbundle via symlink) tells agents to hand users a legacy/conversations/<id>link for delegated Cloud conversations, and hardcodeshttps://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:
OpenHandsAPI.app_conversation_ui_url(conversation_id)toskills/openhands-api/scripts/openhands_api.py. It returns the conversation record'sconversation_ui_urlwhen 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>.skills/openhands-api/SKILL.md(delegation checklist item 6, the cURL flow, the minimal Python flow) andskills/openhands-api/README.mdto share that link, and state explicitly thatconversation_urlis the sandbox agent-server API URL and must not be shared as a UI link.npm run build:skills(and any other sync the change requires).Non-goals:
<LOCAL_AGENT_SERVER_URL>/conversations/<id>stays as written. Only the Cloud app-conversation path moves under/canvas.scripts/openhands_api.ts); it has no conversation-lookup helper today./conversations/<id>links (github-issue-to-pr,gitlab-issue-to-mr,slack-channel-monitor,news-digest, and similar); those are separate follow-up work.Acceptance Criteria
OpenHandsAPI.app_conversation_ui_url(conversation_id)exists inskills/openhands-api/scripts/openhands_api.pyand returns the value of the conversation record'sconversation_ui_urlwhen the app server returns that field.conversation_ui_url(or returns it empty/null), the helper returns<base_url>/canvas/conversations/<conversation_id>using the client's configuredbase_url(no hardcodedapp.all-hands.dev).skills/openhands-api/SKILL.mdno longer instructs agents to sharehttps://app.all-hands.dev/conversations/<id>and instead points at the helper's Agent Canvas link, and it explicitly says not to shareconversation_urlas a UI link.SKILL.md, plusskills/openhands-api/README.md, present the Agent Canvas link (<host>/canvas/conversations/<id>) for delegated conversations and identifyconversation_urlas the sandbox agent-server API URL.<LOCAL_AGENT_SERVER_URL>/conversations/<id>) is left unchanged, since standalone local Agent Canvas serves the UI at the root.tests/test_openhands_api_python.pycover both the server-providedconversation_ui_urland the fallback path; they fail before the change and pass after.python scripts/sync_extensions.py --checkandnpm run build:skillsleave the working tree clean.