* Add multi-step onboarding modal with agent/backend/LLM/hello steps
Adds a four-step welcome flow that appears on first visit (gated by an
`openhands-onboarded` localStorage flag) on the home route:
0. Choose Agent — OpenHands selectable, Claude Code & Codex disabled
with a "coming soon" note
1. Check Backend — embeds the existing backend edit form, plus a
live connection banner driven by useBackendsHealth
2. Set up LLM — embeds the existing LlmSettingsScreen
3. Say hello — pre-filled greeting input that launches a fresh
conversation with no workspace
Each step lives in its own panel; advancing slides the rail
horizontally for the slide-in-from-the-right animation. A top progress
bar reflects the current step.
Also extracts a reusable BackendForm out of BackendFormModal so the
backend step can render the same form inline, and adds an
`onSaveSuccess` hook to LlmSettingsScreen so the onboarding flow can
auto-advance after saving.
Tests: 14 new tests cover the progress bar, completion hook, agent
chooser, and full modal navigation.
Co-authored-by: openhands <openhands@all-hands.dev>
* Fix onboarding slide rail layout & promote 'coming soon' note
Two related fixes for the onboarding modal:
1. Slide rail was using `width: 400%` + `translateX(-N * 100%)` on the
rail itself. CSS translate percentages are relative to the
*element's own* width, so on step 2 the rail shifted by its full
2240px width — pushing all step content off-screen and leaving an
empty modal sized to the tallest step. Reworked the rail so each
slide now translates by `(index - currentStep) * 100%` of its own
width, with inactive slides absolute-positioned (`inset-0`) inside
a relative parent. Active slide drives the modal height; inactive
slides no longer contribute vertical space, eliminating the
funky-overhang behavior.
2. Moved the 'Support for other agents coming soon!' note from a tiny
italic line at the bottom of the agent step to a prominent
primary-tinted callout pinned to the top, with a Sparkles icon and
bumped-up typography.
Tests assert per-slide transforms and active state instead of a
single rail transform; existing flow tests still cover the full
0 → 3 progression.
Co-authored-by: openhands <openhands@all-hands.dev>
* Polish onboarding LLM step: embed inline + default to Anthropic/Opus
The third onboarding step embedded `LlmSettingsScreen` as-is, which
brought along the screen's sticky `bg-base` save bar. In the modal
that rendered as a dark stripe overlapping the rest of the form, and
the existing per-step Next button created a confusing duplicate CTA
alongside Save Changes.
- Add an `embedded` prop to `SdkSectionPage` (and forward it through
`LlmSettingsScreen`) that drops the sticky positioning + contrast
background so the Save button just sits inline at the bottom of
the form, blending with the modal panel.
- Add an `initialValueOverrides` prop to `SdkSectionPage` that wins
over `useSettings`-derived defaults and pre-marks the overridden
keys dirty so the Save button is enabled on mount. Use it from the
onboarding LLM step to pin the model to
`anthropic/claude-opus-4-5-20251101` per the spec, instead of the
global OpenHands-prefixed default.
- Drop the redundant `onboarding-llm-next` button. Saving is now the
primary advance action via the existing `onSaveSuccess` hook; a
small "Skip for now" link remains for users who want to fill this
in later.
Onboarding modal test updated to drive step 2 to step 3 via the skip
link.
Co-authored-by: openhands <openhands@all-hands.dev>
* Drive LLM step's save from the onboarding Next button
The previous polish pass left the LLM settings form's "Save Changes"
button visible inside the onboarding modal, with a separate "Skip for
now" link doing the advancing. That's the wrong shape for an
onboarding flow — every other step has a single primary Next button at
the modal footer, and the user expects clicking Next to commit the
form and advance.
- Add `hideSaveButton` and `onSaveControlChange` props to
`SdkSectionPage` (forwarded through `LlmSettingsScreen`). The first
suppresses the built-in Save button + the `pb-20` placeholder it
reserved; the second hands the parent a stable `save()` callback
plus `{ isSaving, isDirty }` state so it can render its own button.
- Rebuild `SetupLlmStep`'s footer as a single primary "Next" button
matching the Backend step. Clicking Next:
* triggers `saveControl.save()` if there are dirty fields;
`onSaveSuccess` (wired to `onNext`) advances when the mutation
resolves successfully.
* falls through to `onNext()` when nothing is dirty, so users
with already-configured settings aren't blocked.
The Next button stays disabled while a save is in flight.
- Drop the previously-added "Skip for now" affordance — Next now
covers the no-dirty-fields case.
- Restore the test selector to `onboarding-llm-next` so the modal
test continues to drive step 2 → 3 the way users will.
Co-authored-by: openhands <openhands@all-hands.dev>
---------
Co-authored-by: openhands <openhands@all-hands.dev>
agent-canvas
Warning
This project is in sandbox phase. It may be vibecoded, untested, or out of date. OpenHands takes no responsibility for the code or its support. Learn more.
Agent Canvas is a web frontend for managing agents. You can:
- ⌨️ prompt them manually
- 🕐 run them on a schedule
- ⚡ trigger them automatically—e.g. from Slack or GitHub.
Agents can run anywhere:
- 🧑💻 on your laptop
- 🖥️ on a remote virtual machine
- ☁️ in our hosted cloud
- 🏢 or inside your company’s infrastructure
You can work with any agent (e.g. Claude Code, Codex) or connect directly to an LLM (e.g. Anthropic, OpenAI, Gemini, Mistral, Minimax, Kimi).
If you have questions or feedback, please open a GitHub issue or join the #proj-agent-canvas channel in Slack
Quickstart
With Docker (recommended)
Prerequisites:
- Node.js 22.12.x or later
npm- Docker
Set $PROJECT_PATH to the directory on your machine where your projects live (e.g. /path/to/your/projects). The agent server will mount this directory so the agent can read and edit your code.
export PROJECT_PATH=/path/to/your/projects
git clone https://github.com/OpenHands/agent-canvas.git
cd agent-canvas
npm install
npm run dev:docker
Access the UI at http://localhost:8000
Without Docker
Warning
This runs the agent-server directly on the machine you're installing on--the agent will have full access to your filesystem!
Prerequisites:
- Node.js 22.12.x or later
npmuv(for running the agent server viauvx)
git clone https://github.com/OpenHands/agent-canvas.git
cd agent-canvas
npm install
npm run dev:dangerously-dockerless
Access the UI at http://localhost:8000
Architecture
Agent Canvas is powered by the OpenHands Agent Server, a REST API for running multiple agents on a single machine. Each Agent Server runs on a single host/port; the Agent Canvas can connect to multiple Agent Servers and easily flip between them.
You can run an Agent Server anywhere:
- Directly on your laptop (be careful!)
- Inside a Docker container
- On a dedicated machine like a Mac Mini
- On a virtual machine in the cloud
- Inside a Kubernetes Pod
- Inside OpenHands Cloud (our commercial offering)
The Agent Server is often paired with an Automation Server, which lets you set up agents that run on a schedule or in response to events.
More documentation
For contributor and developer workflows, including frontend-only mode, mock mode, environment variables, and build/test commands, see DEVELOPMENT.md.