Skip to content

Serve bundled agent-canvas frontend from agent-server#3675

Draft
enyst wants to merge 1 commit into
mainfrom
openhands/start-agent-canvas-frontend
Draft

Serve bundled agent-canvas frontend from agent-server#3675
enyst wants to merge 1 commit into
mainfrom
openhands/start-agent-canvas-frontend

Conversation

@enyst

@enyst enyst commented Jun 11, 2026

Copy link
Copy Markdown
Member

HUMAN:

  • A human has tested these changes.

AGENT:


Why

Fixes #3658. Python-only users should be able to start agent-server and get the agent-canvas UI from the same process/port when the prebuilt frontend is packaged with openhands-agent-server.

Summary

  • Adds bundled frontend path detection and an OH_FRONTEND_FILES_PATH-configurable frontend build path.
  • Serves agent-canvas root-relative assets and SPA fallback routes from FastAPI after API/WebSocket routes, while keeping API-like paths from falling back to index.html.
  • Adds package/PyInstaller data inclusion and a release helper that fetches the published @openhands/agent-canvas build before PyPI package builds.

Issue Number

Fixes #3658

How to Test

  • uv run pytest tests/agent_server/test_api.py -q — 44 passed.
  • uv run pre-commit run --files .gitignore openhands-agent-server/openhands/agent_server/api.py openhands-agent-server/openhands/agent_server/config.py openhands-agent-server/openhands/agent_server/frontend.py openhands-agent-server/openhands/agent_server/agent-server.spec openhands-agent-server/pyproject.toml tests/agent_server/test_api.py .github/scripts/fetch_agent_canvas_frontend.py .github/workflows/pypi-release.yml — passed.
  • Created a temporary fake openhands-agent-server/openhands/agent_server/frontend/ build, ran uv build --package openhands-agent-server --wheel --out-dir /tmp/agent-server-build-test, and verified the wheel contained openhands/agent_server/frontend/index.html and openhands/agent_server/frontend/assets/app.js.
  • Ran python .github/scripts/fetch_agent_canvas_frontend.py --target /tmp/agent-canvas-frontend-test and verified the fetched package produced /tmp/agent-canvas-frontend-test/index.html and an assets/ directory.

Video/Screenshots

No screenshot was captured. The FastAPI route behavior was exercised with TestClient: / serves index.html, /assets/app.js serves a real root-relative asset, SPA routes fall back to index.html, missing assets return 404, and missing /api/* paths return JSON 404s instead of frontend HTML.

Type

  • Bug fix
  • Feature
  • Refactor
  • Breaking change
  • Docs / chore

Notes

The generated frontend asset directory is intentionally git-ignored; the PyPI release workflow fetches the published agent-canvas build before building distributions so the files are included by package data without committing thousands of generated frontend files.

This PR was created by an AI agent (OpenHands) on behalf of the requester.

@enyst can click here to continue refining the PR


Agent Server images for this PR

GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server

Variants & Base Images

Variant Architectures Base Image Docs / Tags
java amd64, arm64 eclipse-temurin:17-jdk Link
python amd64, arm64 nikolaik/python-nodejs:python3.13-nodejs22-slim Link
golang amd64, arm64 golang:1.21-bookworm Link

Pull (multi-arch manifest)

# Each variant is a multi-arch manifest supporting both amd64 and arm64
docker pull ghcr.io/openhands/agent-server:172bc34-python

Run

docker run -it --rm \
  -p 8000:8000 \
  --name agent-server-172bc34-python \
  ghcr.io/openhands/agent-server:172bc34-python

All tags pushed for this build

ghcr.io/openhands/agent-server:172bc34-golang-amd64
ghcr.io/openhands/agent-server:172bc348510384f1826664aaaa2039ace4788a10-golang-amd64
ghcr.io/openhands/agent-server:openhands-start-agent-canvas-frontend-golang-amd64
ghcr.io/openhands/agent-server:172bc34-golang_tag_1.21-bookworm-amd64
ghcr.io/openhands/agent-server:172bc34-golang-arm64
ghcr.io/openhands/agent-server:172bc348510384f1826664aaaa2039ace4788a10-golang-arm64
ghcr.io/openhands/agent-server:openhands-start-agent-canvas-frontend-golang-arm64
ghcr.io/openhands/agent-server:172bc34-golang_tag_1.21-bookworm-arm64
ghcr.io/openhands/agent-server:172bc34-java-amd64
ghcr.io/openhands/agent-server:172bc348510384f1826664aaaa2039ace4788a10-java-amd64
ghcr.io/openhands/agent-server:openhands-start-agent-canvas-frontend-java-amd64
ghcr.io/openhands/agent-server:172bc34-eclipse-temurin_tag_17-jdk-amd64
ghcr.io/openhands/agent-server:172bc34-java-arm64
ghcr.io/openhands/agent-server:172bc348510384f1826664aaaa2039ace4788a10-java-arm64
ghcr.io/openhands/agent-server:openhands-start-agent-canvas-frontend-java-arm64
ghcr.io/openhands/agent-server:172bc34-eclipse-temurin_tag_17-jdk-arm64
ghcr.io/openhands/agent-server:172bc34-python-amd64
ghcr.io/openhands/agent-server:172bc348510384f1826664aaaa2039ace4788a10-python-amd64
ghcr.io/openhands/agent-server:openhands-start-agent-canvas-frontend-python-amd64
ghcr.io/openhands/agent-server:172bc34-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-amd64
ghcr.io/openhands/agent-server:172bc34-python-arm64
ghcr.io/openhands/agent-server:172bc348510384f1826664aaaa2039ace4788a10-python-arm64
ghcr.io/openhands/agent-server:openhands-start-agent-canvas-frontend-python-arm64
ghcr.io/openhands/agent-server:172bc34-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-arm64
ghcr.io/openhands/agent-server:172bc34-golang
ghcr.io/openhands/agent-server:172bc348510384f1826664aaaa2039ace4788a10-golang
ghcr.io/openhands/agent-server:openhands-start-agent-canvas-frontend-golang
ghcr.io/openhands/agent-server:172bc34-golang_tag_1.21-bookworm
ghcr.io/openhands/agent-server:172bc34-java
ghcr.io/openhands/agent-server:172bc348510384f1826664aaaa2039ace4788a10-java
ghcr.io/openhands/agent-server:openhands-start-agent-canvas-frontend-java
ghcr.io/openhands/agent-server:172bc34-eclipse-temurin_tag_17-jdk
ghcr.io/openhands/agent-server:172bc34-python
ghcr.io/openhands/agent-server:172bc348510384f1826664aaaa2039ace4788a10-python
ghcr.io/openhands/agent-server:openhands-start-agent-canvas-frontend-python
ghcr.io/openhands/agent-server:172bc34-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim

About Multi-Architecture Support

  • Each variant tag (e.g., 172bc34-python) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., 172bc34-python-amd64) are also available if needed

Co-authored-by: openhands <openhands@all-hands.dev>
@github-actions

Copy link
Copy Markdown
Contributor

Python API breakage checks — ✅ PASSED

Result:PASSED

Action log

@github-actions

Copy link
Copy Markdown
Contributor

REST API breakage checks (OpenAPI) — ✅ PASSED

Result:PASSED

Action log

@github-actions

Copy link
Copy Markdown
Contributor

Coverage

Coverage Report •
FileStmtsMissCoverMissing
openhands-agent-server/openhands/agent_server
   api.py2942491%105, 107–112, 114, 116, 118, 152, 164, 179, 185, 376–377, 414, 531, 534, 538–540, 542, 549
   config.py74297%30, 43
   frontend.py8187%13
TOTAL309281347756% 

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Start agent-canvas frontend from this repository

1 participant