diff --git a/llms-full.txt b/llms-full.txt index 3d03b70d..63603200 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -14,6 +14,7 @@ You can use the OpenHands Software Agent SDK for: - One-off tasks, like building a README for your repo - Routine maintenance tasks, like updating dependencies - Major tasks that involve multiple agents, like refactors and rewrites +- OpenAI-compatible access to an OpenHands agent from chat UIs, IDEs, voice platforms, and other clients You can even use the SDK to build new developer experiences—it’s the engine behind the [OpenHands CLI](/openhands/usage/cli/quick-start) and [OpenHands Cloud](/openhands/usage/cloud/openhands-cloud). @@ -21,7 +22,7 @@ Get started with some examples or keep reading to learn more. ## Features - + A unified Python API that enables you to run agents locally or in the cloud, define custom agent behaviors, and create custom tools. @@ -31,6 +32,13 @@ Get started with some examples or keep reading to learn more. A production-ready server that runs agents anywhere, including Docker and Kubernetes, while connecting seamlessly to the Python API. + + Access the OpenHands agent via an OpenAI-compatible endpoint for chat UIs, IDEs, voice platforms, and other OpenAI-style clients. + ## Why OpenHands Software Agent SDK? @@ -6658,6 +6666,7 @@ For full list of implemented workspaces, see the [source code](https://github.co **Features:** - REST API & WebSocket endpoints for conversations, bash, files, events, desktop, and VSCode +- [OpenAI-compatible `/v1/chat/completions` endpoint](/sdk/guides/agent-server/openai-gateway) for clients that expect an OpenAI-style backend - Service management with isolated per-user sessions - API key authentication and health checking @@ -9217,9 +9226,9 @@ Each `AgentContext` field is tagged as ACP-compatible or not. At initialization, | `load_user_skills` | ✅ | Load skills from `~/.openhands/skills/` | | `load_public_skills` | ✅ | Load skills from the public extensions repo | | `marketplace_path` | ✅ | Filter public skills via marketplace JSON | -| `secrets` | ❌ | ACP subprocesses do not use OpenHands secret injection | +| `secrets` | ✅ | Injected into the ACP subprocess environment (and masked if the server echoes them back) | -Passing `secrets` (or any future field marked `acp_compatible: False`) raises `NotImplementedError`. +Any `AgentContext` field marked `acp_compatible: False` raises `NotImplementedError` at initialization. ### What ACPAgent Does Not Support @@ -9263,7 +9272,6 @@ If you attach to an existing conversation by `conversation_id`, use `ACPAgent` f agent = ACPAgent( acp_command=["npx", "-y", "@agentclientprotocol/claude-agent-acp"], acp_args=["--profile", "my-profile"], # extra CLI args - acp_env={"ANTHROPIC_API_KEY": "sk-..."}, # extra env vars ) ``` @@ -9271,7 +9279,23 @@ agent = ACPAgent( |-----------|-------------| | `acp_command` | Command to start the ACP server (required) | | `acp_args` | Additional arguments appended to the command | -| `acp_env` | Additional environment variables for the server process | +| `acp_env` | **Deprecated** (removed in 1.29.0). Route env/credentials through the conversation's `secrets` or `agent_context.secrets` instead — see below. | + +### Environment Variables and Credentials + +Pass the environment variables and credentials the ACP server needs through the conversation's `secrets` (or `agent_context.secrets`). They flow into the conversation's secret registry, are injected into the ACP subprocess environment, and are masked if the server echoes them back into its output: + +```python icon="python" +conversation = Conversation( + agent=agent, + workspace="./my-project", + secrets={"ANTHROPIC_API_KEY": "sk-..."}, +) +``` + + +`acp_env` still works but is deprecated and will be removed in 1.29.0; prefer the secret-registry channels above for environment variables and credentials. + ### Authentication @@ -13325,6 +13349,371 @@ with ManagedAPIServer(port=8001) as server: - **[Agent Server Overview](/sdk/guides/agent-server/overview)** - Architecture and implementation details - **[Agent Server Package Architecture](/sdk/arch/agent-server)** - Remote execution architecture +### OpenAI-Compatible Endpoint +Source: https://docs.openhands.dev/sdk/guides/agent-server/openai-gateway.md + +import RunExampleCode from "/sdk/shared-snippets/how-to-run-example.mdx"; + +The agent-server exposes an OpenAI-compatible `/v1/chat/completions` endpoint so clients that already speak the OpenAI protocol can call an OpenHands agent. + +Use this when you want an existing chat UI, IDE integration, evaluation harness, voice platform, or another agent to treat OpenHands as an OpenAI-style backend while still getting the full agent runtime behind the request. + +## What to Configure + +Most OpenAI-compatible clients ask for the same three fields: + +| Client Field | Value | +| --- | --- | +| Base URL | `https://YOUR_AGENT_SERVER/v1` | +| API key | Your agent-server session API key | +| Model | `openhands_` | + +For example, a saved LLM profile named `gateway_demo` appears as the OpenAI model `openhands_gateway_demo`. + +The gateway accepts the same session key in either OpenHands or OpenAI-compatible form: + +- `X-Session-API-Key: ` +- `Authorization: Bearer ` + +## Prepare a Profile + +OpenAI-compatible traffic is backed by an agent-server LLM profile. Create one with the native profile API first: + +```bash +export AGENT_SERVER_URL="http://localhost:8000" +export SESSION_API_KEY="your-session-api-key" +export PROFILE_NAME="gateway_demo" +export OPENHANDS_MODEL="openhands_${PROFILE_NAME}" + +curl -X POST "$AGENT_SERVER_URL/api/profiles/$PROFILE_NAME" \ + -H "X-Session-API-Key: $SESSION_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "llm": { + "model": "gpt-5-nano", + "api_key": "YOUR_LLM_API_KEY" + }, + "include_secrets": true + }' +``` + +Then confirm the profile is visible to OpenAI clients: + +```bash +curl "$AGENT_SERVER_URL/v1/models" \ + -H "Authorization: Bearer $SESSION_API_KEY" +``` + +## Client Recipes + + + + +```bash +curl -i "$AGENT_SERVER_URL/v1/chat/completions" \ + -H "Authorization: Bearer $SESSION_API_KEY" \ + -H "Content-Type: application/json" \ + -d "{ + \"model\": \"$OPENHANDS_MODEL\", + \"messages\": [ + { + \"role\": \"system\", + \"content\": \"Answer directly unless you need to inspect files.\" + }, + { + \"role\": \"user\", + \"content\": \"Explain what this OpenHands endpoint does in one sentence.\" + } + ] + }" +``` + +The response includes `X-OpenHands-ServerConversation-ID`. Save that header if you want a later request to continue the same agent conversation. + + + + +```python +import os + +from openai import OpenAI + +client = OpenAI( + api_key=os.environ["SESSION_API_KEY"], + base_url=f"{os.environ['AGENT_SERVER_URL']}/v1", +) + +response = client.chat.completions.with_raw_response.create( + model=os.environ["OPENHANDS_MODEL"], + messages=[ + {"role": "user", "content": "Summarize this repository."}, + ], +) +completion = response.parse() +conversation_id = response.headers["X-OpenHands-ServerConversation-ID"] +print(completion.choices[0].message.content) + +follow_up = client.chat.completions.create( + model=os.environ["OPENHANDS_MODEL"], + messages=[{"role": "user", "content": "Now list the main packages."}], + extra_headers={"X-OpenHands-ServerConversation-ID": conversation_id}, +) +print(follow_up.choices[0].message.content) +``` + + + + +```javascript +import OpenAI from "openai"; + +const client = new OpenAI({ + apiKey: process.env.SESSION_API_KEY, + baseURL: `${process.env.AGENT_SERVER_URL}/v1`, +}); + +const first = await client.chat.completions + .create({ + model: process.env.OPENHANDS_MODEL, + messages: [ + { role: "user", content: "Summarize this repository." }, + ], + }) + .withResponse(); + +const conversationId = first.response.headers.get( + "x-openhands-serverconversation-id", +); +console.log(first.data.choices[0].message.content); + +const followUp = await client.chat.completions.create( + { + model: process.env.OPENHANDS_MODEL, + messages: [{ role: "user", content: "Now list the main packages." }], + }, + { + headers: { "X-OpenHands-ServerConversation-ID": conversationId }, + }, +); +console.log(followUp.choices[0].message.content); +``` + + + + +For Open WebUI, LibreChat, Chatbot UI, and similar OpenAI-compatible frontends, configure a custom OpenAI provider with: + +- **Base URL**: `https://YOUR_AGENT_SERVER/v1` +- **API key**: your agent-server session API key +- **Model**: `openhands_` +- **Streaming**: disabled for now + +If the UI can store a response header and send a custom request header, persist `X-OpenHands-ServerConversation-ID` per chat thread and send it on follow-up turns. If it cannot, each request starts a new OpenHands conversation and works best for one-shot tasks. + + + + +Voice platforms and webhook integrations usually have their own session or call ID. Store a mapping from that external ID to the OpenHands conversation ID: + +```python +import os + +# Initialize this once at app startup, or replace it with durable session storage. +conversation_ids: dict[str, str] = {} + +conversation_id = conversation_ids.get(platform_session_id) +headers = {} +if conversation_id: + headers["X-OpenHands-ServerConversation-ID"] = conversation_id + +response = client.chat.completions.with_raw_response.create( + model=os.environ.get("OPENHANDS_MODEL", "openhands_gateway_demo"), + messages=[{"role": "user", "content": transcript_text}], + extra_headers=headers, +) + +conversation_ids[platform_session_id] = response.headers[ + "X-OpenHands-ServerConversation-ID" +] +reply_text = response.parse().choices[0].message.content +``` + +Return `reply_text` to the voice or webhook platform. Keep the mapping for as long as that external session should continue. + + + + +## Conversation State + +The OpenAI Chat Completions protocol usually sends full message history on every request. The OpenHands gateway does not reconstruct agent history from prior assistant messages. Instead: + +- Omit `X-OpenHands-ServerConversation-ID` to start a new OpenHands conversation. +- Read `X-OpenHands-ServerConversation-ID` from the response. +- Send that header on follow-up requests to continue the same OpenHands conversation. + +When reusing a conversation, send the newest user turn in `messages`. The server-side OpenHands conversation owns the previous agent state, tool activity, and workspace context. + +## Current Limitations + +- Only non-streaming Chat Completions requests are supported. Requests with `stream: true` return `400` until streaming support is added. +- The response contains the final assistant text only. Internal OpenHands tool activity is not exposed as OpenAI tool calls. +- OpenAI request fields that are not needed by the gateway are ignored or rejected intentionally by the server implementation. + +## Ready-to-run example + + +This example is available on GitHub: [examples/02_remote_agent_server/15_openai_compatible_gateway.py](https://github.com/OpenHands/software-agent-sdk/blob/main/examples/02_remote_agent_server/15_openai_compatible_gateway.py) + + +```python icon="python" expandable examples/02_remote_agent_server/15_openai_compatible_gateway.py +"""Use the agent-server through an OpenAI-compatible Chat Completions client. + +This example starts a local agent-server, stores an LLM profile, lists it through +``GET /v1/models``, then calls ``POST /v1/chat/completions`` with the OpenAI +Python SDK. The returned ``X-OpenHands-ServerConversation-ID`` header is passed +back on a second call to continue the same OpenHands conversation. +""" + +import os +from uuid import UUID + +import httpx +from openai import OpenAI +from scripts.utils import ManagedAPIServer + + +# The gateway runs a full OpenHands agent, but OpenAI clients still need a +# normal model-like name. We create an LLM profile below and expose it as +# `openhands_` through `/v1/models`. + +api_key = os.getenv("LLM_API_KEY") or os.getenv("OPENAI_API_KEY") +assert api_key is not None, "Set LLM_API_KEY or OPENAI_API_KEY." + +llm_model = os.getenv("LLM_MODEL", "gpt-5-nano") +llm_base_url = os.getenv("LLM_BASE_URL") +profile_name = "gateway_demo" +gateway_model = f"openhands_{profile_name}" + +# Start a local agent-server for the demo. `use_session_api_key=True` turns on +# authentication; the same key works as both `X-Session-API-Key` for native +# agent-server routes and `Authorization: Bearer ...` for OpenAI SDK calls. + +with ManagedAPIServer( + port=8770, + use_session_api_key=True, + extra_env={ + "OH_ENABLE_VNC": "0", + "OH_ENABLE_VSCODE": "0", + "OH_PRELOAD_TOOLS": "0", + "OH_SECRET_KEY": "example-secret-key-for-demo-only-32b", + "OH_WEBHOOKS": "[]", + }, + health_request_timeout=2.0, +) as server: + session_api_key = ( + os.getenv("SESSION_API_KEY") + or os.getenv("OH_SESSION_API_KEYS_0") + or server.session_api_key + ) + assert session_api_key is not None + + # Use the native REST API once to create the profile that backs the gateway + # model. After that, normal OpenAI SDK calls are enough for chat traffic. + api_client = httpx.Client( + base_url=server.base_url, + headers={"X-Session-API-Key": session_api_key}, + timeout=120.0, + ) + openai_client = OpenAI( + api_key=session_api_key, + base_url=f"{server.base_url}/v1", + timeout=120.0, + ) + + llm_config = {"model": llm_model, "api_key": api_key} + if llm_base_url: + llm_config["base_url"] = llm_base_url + + # `gateway_demo` becomes visible to OpenAI clients as `openhands_gateway_demo`. + profile_response = api_client.post( + f"/api/profiles/{profile_name}", + json={"llm": llm_config, "include_secrets": True}, + ) + assert profile_response.status_code == 201, profile_response.text + + models = openai_client.models.list() + model_ids = [model.id for model in models.data] + assert gateway_model in model_ids + print(f"Gateway models include: {gateway_model}") + + # Ask through the OpenAI SDK. `with_raw_response` lets us read the custom + # response header that identifies the OpenHands conversation created behind + # this otherwise OpenAI-shaped request. + + first_response = openai_client.chat.completions.with_raw_response.create( + model=gateway_model, + messages=[ + { + "role": "system", + "content": "Answer directly and do not use tools.", + }, + { + "role": "user", + "content": ( + "In one sentence, explain what an OpenAI-compatible " + "agent-server gateway does." + ), + }, + ], + ) + first_completion = first_response.parse() + conversation_id = first_response.headers.get("X-OpenHands-ServerConversation-ID") + assert conversation_id is not None + UUID(conversation_id) + + first_answer = first_completion.choices[0].message.content + print(f"First answer: {first_answer}") + print(f"OpenHands conversation ID: {conversation_id}") + + persisted_response = api_client.get(f"/api/conversations/{conversation_id}") + assert persisted_response.status_code == 200, persisted_response.text + + # The gateway keeps conversations by default. Passing the header back lets + # another OpenAI-compatible request continue the same server-side agent + # conversation instead of starting over. + + second_completion = openai_client.chat.completions.create( + model=gateway_model, + messages=[ + { + "role": "user", + "content": "Now answer in five words or fewer: what did I ask about?", + } + ], + extra_headers={"X-OpenHands-ServerConversation-ID": conversation_id}, + ) + second_answer = second_completion.choices[0].message.content + print(f"Second answer using same conversation: {second_answer}") + + conversation_response = api_client.get(f"/api/conversations/{conversation_id}") + assert conversation_response.status_code == 200, conversation_response.text + stats = conversation_response.json().get("stats") or {} + usage_to_metrics = stats.get("usage_to_metrics") or {} + accumulated_cost = sum( + metrics.get("accumulated_cost", 0.0) for metrics in usage_to_metrics.values() + ) + + # Clean up the demo resources. Real applications can keep the conversation + # ID and inspect it later through the native agent-server API. + api_client.delete(f"/api/conversations/{conversation_id}") + api_client.delete(f"/api/profiles/{profile_name}") + api_client.close() + + print(f"EXAMPLE_COST: {accumulated_cost}") +``` + + + ### Overview Source: https://docs.openhands.dev/sdk/guides/agent-server/overview.md @@ -13368,6 +13757,7 @@ A Remote Agent Server is an HTTP/WebSocket server that: - **Manages workspaces** (Docker containers or remote sandboxes) - **Streams events** to clients via WebSocket - **Handles command and file operations** (execute command, upload, download), check [base class](https://github.com/OpenHands/software-agent-sdk/blob/main/openhands-sdk/openhands/sdk/workspace/base.py) for more details +- **Accepts OpenAI-compatible Chat Completions requests** through the [OpenAI-compatible endpoint](/sdk/guides/agent-server/openai-gateway) - **Provides isolation** between different agent executions Think of it as the "backend" for your agent, while your Python code acts as the "frontend" client. @@ -13484,6 +13874,7 @@ Explore different deployment options: - **[Local Agent Server](/sdk/guides/agent-server/local-server)** - Run agent server in the same process - **[Docker Sandboxed Server](/sdk/guides/agent-server/docker-sandbox)** - Run agent server in isolated Docker containers - **[API Sandboxed Server](/sdk/guides/agent-server/api-sandbox)** - Connect to hosted agent server via API +- **[OpenAI-Compatible Endpoint](/sdk/guides/agent-server/openai-gateway)** - Access an OpenHands agent from OpenAI-compatible clients For architectural details: - **[Agent Server Package Architecture](/sdk/arch/agent-server)** - Remote execution architecture and deployment @@ -28469,6 +28860,1539 @@ If you encounter issues with the search functionality: - Ensure you have an active internet connection. - Check Tavily's status page for any service disruptions. +### ACP Agents +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/acp-agents.md + +Agent Canvas can drive your conversations with the built-in **OpenHands** agent or with an external **ACP agent** — Claude Code, Codex, or Gemini CLI. This guide explains what ACP agents are, how to onboard one, and how to switch agents or models later. + +## What is an ACP agent? + +The [Agent Client Protocol (ACP)](https://agentclientprotocol.com/protocol/overview) is a standard for talking to coding agents over JSON-RPC on stdio. Instead of Agent Canvas calling an LLM directly, the Agent Server spawns the agent's own CLI as a subprocess and relays each turn to it. The external agent manages its own LLM, tools, and execution; Agent Canvas sends messages and renders what comes back. + +```mermaid +flowchart LR + canvas["Agent Canvas
(this UI)"] + server["Agent Server"] + acp["ACP subprocess
(e.g. claude-agent-acp)"] + llm["LLM provider
(Anthropic / OpenAI / Google)"] + canvas -- "PATCH /api/settings
(agent_kind, acp_*)" --> server + canvas -- "conversation turns" --> server + server -- "spawn + JSON-RPC over stdio" --> acp + acp -- "API calls" --> llm +``` + +The Agent Server owns the subprocess and the credentials; Agent Canvas only records *which* agent to run and surfaces a form for the secrets it needs. The agent choice is stored per backend, so switching backends can switch agents. + +## Supported providers + +| Provider | Default command | +|---|---| +| **Claude Code** | `npx -y @agentclientprotocol/claude-agent-acp` | +| **Codex** | `npx -y @zed-industries/codex-acp` | +| **Gemini CLI** | `npx -y @google/gemini-cli --acp` | + +The provider list is sourced from the OpenHands SDK registry (`openhands.sdk.settings.acp_providers`, mirrored into `@openhands/typescript-client`) and enriched with Canvas UI metadata. Adding or changing a provider happens upstream in the SDK. + +## Authentication + + + ACP agents authenticate **two ways: a subscription login, or an API key** — and the onboarding fields are optional. If you're already signed in to the provider's CLI on the machine the agent runs on, it reuses that login automatically, so locally you often don't need a key at all. **The login takes priority over an API key:** while you're signed in, a key set in the environment isn't used — so the onboarding key fields do nothing and can be left blank. + + +A "subscription login" is the credential the provider's own CLI stores when you sign in once — a file in your home directory, or, for Claude Code on macOS, the system **Keychain**. When the Agent Server runs **on that same machine** (a local or self-hosted backend), the provider CLI finds that login automatically — no API key required. On a clean cloud sandbox there's no stored login, so an API key is needed instead. + +| Provider | Subscription login (auto-detected) | API key | +|---|---|---| +| **Claude Code** | A Claude Code login (Pro/Max), from Claude Code's own credential store: the **macOS Keychain**, or `~/.claude/.credentials.json` on Linux | `ANTHROPIC_API_KEY` | +| **Codex** | A ChatGPT login (`codex login`) cached at `~/.codex/auth.json` | `OPENAI_API_KEY` | +| **Gemini CLI** | Your Google login (`gemini`/`gemini --acp`) cached at `~/.gemini/oauth_creds.json` | `GEMINI_API_KEY` | + +All three collect an *optional* API key (plus base URL) in onboarding. As noted above, a subscription / OAuth login takes priority over an API key — when the provider's CLI is signed in, a key set in the environment is not used: + +- **Codex** — `codex login status` keeps reporting the ChatGPT login even with `OPENAI_API_KEY` set. +- **Gemini CLI** — uses the OAuth auth type chosen at `gemini` login; `GEMINI_API_KEY` is only consulted if you switch the auth type. The free Google login is the common no-key path locally — sign in once and it just works. +- **Claude Code** — with both present, `claude auth status` reports it is authenticated via the subscription (`claude.ai`), not the key. The login is auto-detected from the macOS Keychain (or `~/.claude/.credentials.json` on Linux); `CLAUDE_CONFIG_DIR` is **not** required for it — it only relocates Claude Code's config directory (settings/history, not the token) and signals the SDK to strip a conflicting `ANTHROPIC_API_KEY` / `ANTHROPIC_BASE_URL`. + +The one exception is the **base URL** (`*_BASE_URL`): a custom value points the CLI at a different endpoint (a proxy or gateway) and *does* take effect even under a login — for Gemini it rides the ACP `gateway` param. It's an advanced override, not needed for normal use. + +## Onboarding an ACP agent + +First-time users get a four-step onboarding modal. To onboard an ACP agent: + +1. **Choose agent** — pick Claude Code, Codex, or Gemini CLI instead of OpenHands. The choice is saved immediately to your backend's settings. +2. **Check backend** — confirms Agent Canvas can reach the Agent Server. +3. **Set up credentials** — enter the provider's API key (and, optionally, a custom base URL for a proxy or gateway). All three providers collect these here, and every field is optional. +4. **Say hello** — creates your first conversation and closes the modal. + + + Every credential field is optional and the step is skippable. Leave a field blank to reuse a key already set on the backend, or to authenticate the agent through a subscription / OAuth login instead. + + +### How credentials reach the agent + +Each credential you enter is saved as a **global secret** whose name is exactly the environment variable the Agent Server exports into the ACP subprocess (e.g. `ANTHROPIC_API_KEY`). Saving in onboarding is identical to adding the secret under **Settings → Secrets**, where you can edit or remove it anytime. Keeping the secret name equal to the env var is what makes a saved key actually reach the provider CLI. + +## Switching agent or model later + +Open **Settings → Agent** at any time: + +- **Agent** — switch between **OpenHands** and **ACP**. +- **Preset** — pick a built-in provider (Claude Code, Codex, Gemini CLI) or **Custom** to point at any other ACP server. +- **Command** — the command line used to spawn the subprocess. Selecting a preset fills this in; editing it to match another preset re-detects that provider. API keys are *not* entered here — they live in the Secrets panel. +- **Model** — choose a suggested model for the provider or enter a custom model override. Built-in providers save a concrete model rather than leaving it blank. + +Saving writes an `agent_settings_diff` (`agent_kind`, `acp_server`, `acp_command`, `acp_model`) to `PATCH /api/settings`. A running conversation keeps the agent it started with; the new choice applies to conversations you start afterward. + +## Custom ACP servers + +Any stdio ACP server works: choose **Custom** in Settings → Agent and enter its launch command. Custom servers have no curated model list, so enter the model ID the server expects (if any) as a custom model. Pass credentials by adding the env vars the server reads as global secrets under **Settings → Secrets**. + +## Related Guides + +- [Customize and Settings](/openhands/usage/agent-canvas/customize-and-settings) +- [LLM Profiles and Model Configuration](/openhands/usage/agent-canvas/llm-profiles) +- [Connect and Manage Backends](/openhands/usage/agent-canvas/backends) + +### Cloud Backend +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/backend-setup/cloud.md + +You can connect Agent Canvas to [OpenHands Cloud](/openhands/usage/cloud/openhands-cloud) as a backend. Conversations and automations then run in OpenHands Cloud's on-demand sandboxes instead of on your local machine. + +## When to Use It + +A Cloud backend is a good fit when you want to: + +- Run agents without tying up local resources +- Use OpenHands Cloud's managed sandboxes and integrations +- Keep your local machine for development while offloading agent work + +## Prerequisites + +- An [OpenHands Cloud](https://app.all-hands.dev) account +- Agent Canvas installed — see [Setup](/openhands/usage/agent-canvas/setup) + +## Add a Cloud Backend + +1. Open Agent Canvas and click the backend switcher in the top bar. +2. Choose **Manage Backends** → **Add Backend**. +3. Click **Login with OpenHands Cloud** and sign in with your account. + +Once connected, select it as the active backend. Conversations will now run in OpenHands Cloud. + +### OpenHands Enterprise + +If your organization runs OpenHands Enterprise, click **Advanced** in the Add Backend flow and enter your enterprise host URL before signing in. + +## What's Different with a Cloud Backend + +- **Sandboxed execution** — each conversation runs in an isolated cloud sandbox rather than on your host filesystem. +- **Cloud integrations** — GitHub, GitLab, Bitbucket, Slack, and other integrations configured in OpenHands Cloud are available. +- **Settings are per-backend** — LLM configuration, secrets, and MCP servers saved against the Cloud backend are independent from your local backend settings. + +## Related Guides + +- [Connect and Manage Backends](/openhands/usage/agent-canvas/backends) +- [OpenHands Cloud](/openhands/usage/cloud/openhands-cloud) +- [Local Backend](/openhands/usage/agent-canvas/backend-setup/local) + +### Docker Backend +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/backend-setup/docker.md + +The official Docker image packages the full Agent Canvas stack — backend and frontend — in a single container. The agent runs inside the container rather than directly on your host, giving you a sandboxed environment out of the box. + +## Prerequisites + +- [Docker](https://docs.docker.com/get-docker/) installed and running (Docker Desktop on macOS/Windows, or Docker Engine on Linux) +- Agent Canvas installed locally (if connecting from another instance) — see [Setup](/openhands/usage/agent-canvas/setup) + +## Run the Official Image + +Mount a persistence directory for settings, secrets, and conversation history, and a projects directory for workspace access. + + + + ```bash + mkdir -p ~/projects ~/.openhands + + docker run -it --rm \ + -p 8000:8000 \ + -v ~/.openhands:/home/openhands/.openhands \ + -v ~/projects:/projects \ + ghcr.io/openhands/agent-canvas:latest + ``` + + + ```powershell + New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.openhands", "$env:USERPROFILE\projects" | Out-Null + + docker run -it --rm ` + -p 8000:8000 ` + -v "$($env:USERPROFILE)\.openhands:/home/openhands/.openhands" ` + -v "$($env:USERPROFILE)\projects:/projects" ` + ghcr.io/openhands/agent-canvas:latest + ``` + + + Docker Desktop for Windows must be installed and running. PowerShell uses backticks (`` ` ``) for line continuation instead of backslashes. + + + + +Agent Canvas is now running at `http://localhost:8000`. The agent can access any project under the mounted `/projects` path. + +### Environment Variables + +Configuration is passed via `-e` flags on `docker run`: + +| Variable | Purpose | +|----------|---------| +| `PORT` | Ingress port inside the container (default `8000`). Map it with `-p :`. | +| `LOCAL_BACKEND_API_KEY` | API key for the server. Auto-generated and persisted if not set. | +| `OH_SECRET_KEY` | Secret used to protect stored settings and secrets. | + + + The agent server can execute arbitrary shell commands inside the container. If exposing it beyond localhost, set `LOCAL_BACKEND_API_KEY` to a strong secret. + + +## Connect from the Frontend + +Start the frontend separately and point it at the container: + +```bash +agent-canvas --frontend-only +``` + +Then add the Docker backend: + +1. Click the backend switcher → **Manage Backends** → **Add Backend**. +2. Fill in: + - **Name** — e.g. `docker-backend` + - **Host / Base URL** — `http://localhost:8000` + - **API Key** — the `LOCAL_BACKEND_API_KEY` value (check container logs if auto-generated) +3. Save and select it as the active backend. + +## Related Guides + +- [Connect and Manage Backends](/openhands/usage/agent-canvas/backends) +- [Local Backend](/openhands/usage/agent-canvas/backend-setup/local) +- [VM / Self-Hosted Installation](/openhands/usage/agent-canvas/backend-setup/vm) + +### Local Backend +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/backend-setup/local.md + +Use `--backend-only` to start a local backend. Each backend runs behind an ingress proxy on its own port. + +## Start a Backend + +```bash +agent-canvas --backend-only +``` + +This starts the backend on `127.0.0.1:8000`. No frontend is served. + +## Running Multiple Backends + +You can run several backends at the same time on different ports — for example, one per project or toolchain: + +```bash +agent-canvas --backend-only --port 8001 +agent-canvas --backend-only --port 8002 +agent-canvas --backend-only --port 8003 +``` + +Each instance gets its own backend and ingress proxy. + +## Connect the Frontend + +Start the frontend separately: + +```bash +agent-canvas --frontend-only +``` + +Then add your backends through **Manage Backends**: + +1. Click the backend switcher → **Manage Backends** → **Add Backend**. +2. Fill in the **Host / Base URL** (e.g. `http://localhost:8001`) and **API Key**. +3. Repeat for each backend you started. + +Switch between them from the backend selector depending on what you're working on. + + + If you just want a quick single-machine setup, running `agent-canvas` without any flags starts the full stack (frontend + backend) on one port. The split approach above is useful when you want multiple backends or want to keep the frontend and backends on separate processes. + + +## Related Guides + +- [Connect and Manage Backends](/openhands/usage/agent-canvas/backends) +- [VM / Self-Hosted Installation](/openhands/usage/agent-canvas/backend-setup/vm) — backend-only or full Canvas on a remote machine +- [Docker Backend](/openhands/usage/agent-canvas/backend-setup/docker) — run in a container + +### VM / Self-Hosted Installation +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/backend-setup/vm.md + +Run Agent Canvas on a VM or dedicated machine when you want an always-on backend, more compute, or a self-hosted Canvas that you can reach from other devices. + + + The agent server can read and write the host filesystem, execute shell commands, access the network, and store secrets. Treat the VM as trusted infrastructure. Use `--public`, a strong `LOCAL_BACKEND_API_KEY`, and a network access control layer before exposing it to the internet. + + +## Choose a Deployment Shape + +Agent Canvas supports two VM runtime modes and several ways to reach them: + +| Setup | Start Command | How You Use It | +|-------|---------------|----------------| +| **Backend only** | `agent-canvas --backend-only --public` | Run only the agent server on the VM. Start `agent-canvas --frontend-only` on your laptop and add the VM URL in **Manage Backends**. | +| **Backend only + ngrok** | `agent-canvas --backend-only --public` and `ngrok http 8000` | Use an ngrok URL as the backend URL. Do not add ngrok OAuth for this mode; rely on `LOCAL_BACKEND_API_KEY` plus a private or temporary URL. | +| **Full Canvas** | `agent-canvas --public` | Serve both the Agent Canvas UI and the backend from the VM. Open the VM, reverse proxy, or ngrok URL in a browser. | +| **Full Canvas + ngrok OAuth** | `agent-canvas --public` and `ngrok http 8000 --traffic-policy-file ~/policy.yml` | Protect the full Canvas URL with an ngrok login policy before users reach Agent Canvas. | + + + Use **backend only** when you want to keep the UI on your laptop and switch between backends. Use **full Canvas** when the VM should serve the browser UI too. + + +## 1. Provision and Secure the VM + +Use any always-on Linux or macOS host. Ubuntu 24.04 LTS with 2 vCPU and 4 GB RAM is enough for a single user. + +Before starting Agent Canvas, restrict inbound traffic: + +- **SSH (`22`)** — allow only your IP address or VPN CIDR. +- **Agent Canvas (`8000`)** — keep closed unless you are using an SSH tunnel. If you expose it through ngrok, nginx, or another proxy, expose only that proxy. +- **HTTP/HTTPS (`80`, `443`)** — open only if you configure a reverse proxy and TLS. + +## 2. Install Prerequisites + +Agent Canvas requires: + +- [Node.js](https://nodejs.org/en/download) 22.12 or later, including `npm`. +- [`uv`](https://docs.astral.sh/uv/getting-started/installation/) for the agent server runtime. +- `git` and `curl`. +- Optional: [`ngrok`](https://ngrok.com/download) for a temporary public URL. +- Optional: `tmux` to keep Agent Canvas and ngrok running after disconnecting from SSH. + +### Ubuntu 22.04 / 24.04 + +Install Node.js 22.x, `uv`, and Agent Canvas: + +```bash +sudo apt-get update +sudo apt-get install -y ca-certificates curl gnupg git + +# Node.js 22.x from NodeSource. +curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - +sudo apt-get install -y nodejs + +# uv for the agent server runtime. +curl -LsSf https://astral.sh/uv/install.sh | sh +source "$HOME/.local/bin/env" + +# Agent Canvas CLI. +sudo npm install -g @openhands/agent-canvas + +node --version +uv --version +agent-canvas --version +``` + + + If your `npm` global prefix is user-writable, omit `sudo` from `npm install -g`. For macOS or other Linux distributions, use the official Node.js, `uv`, and ngrok installation links above instead of the Ubuntu-specific commands. + + +Install optional runtime helpers if needed: + +```bash +sudo apt-get install -y tmux +``` + +Install ngrok only if you plan to expose the VM through ngrok: + +```bash +curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \ + | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null + +echo "deb https://ngrok-agent.s3.amazonaws.com buster main" \ + | sudo tee /etc/apt/sources.list.d/ngrok.list + +sudo apt-get update +sudo apt-get install -y ngrok + +ngrok config add-authtoken +``` + +Get the authtoken from the [ngrok dashboard](https://dashboard.ngrok.com/get-started/your-authtoken). + +## 3. Set the Backend API Key + +Remote and shared deployments should always run in public mode. Public mode requires `LOCAL_BACKEND_API_KEY`. + +Create a local environment file on the VM: + +```bash +cat > ~/.agent-canvas.env <<'EOF_ENV' +export LOCAL_BACKEND_API_KEY="" +EOF_ENV +chmod 600 ~/.agent-canvas.env +source ~/.agent-canvas.env +``` + +Use a high-entropy secret. You will enter this key in Agent Canvas when connecting to the VM backend or opening the full Canvas UI. + +## 4. Start Agent Canvas + + + + Start only the backend on the VM: + + ```bash + source ~/.agent-canvas.env + agent-canvas --backend-only --public + ``` + + Then start the frontend on your laptop: + + ```bash + agent-canvas --frontend-only + ``` + + Add the VM backend in Agent Canvas: + + 1. Click the backend switcher, then select `Manage Backends`. + 2. Click `Add Backend`. + 3. Enter a name, such as `my-vm`. + 4. Enter the **Host / Base URL**: + - `http://localhost:8000` if you use an SSH tunnel. + - The `https://...ngrok-free.app` URL if you use ngrok. + - Your reverse proxy URL if you use nginx or another proxy. + 5. Enter the `LOCAL_BACKEND_API_KEY` from the VM. + 6. Save and select the backend. + + + Start the full UI and backend on the VM: + + ```bash + source ~/.agent-canvas.env + agent-canvas --public + ``` + + Open the VM, reverse proxy, or ngrok URL in a browser. Agent Canvas prompts for the `LOCAL_BACKEND_API_KEY` before allowing backend access. + + + +### Keep It Running with tmux + +Use `tmux` when you want Agent Canvas to keep running after your SSH session disconnects. + + + + ```bash + tmux new-session -d -s canvas + tmux send-keys -t canvas 'source ~/.agent-canvas.env && agent-canvas --backend-only --public' Enter + tmux attach-session -t canvas + ``` + + + ```bash + tmux new-session -d -s canvas + tmux send-keys -t canvas 'source ~/.agent-canvas.env && agent-canvas --public' Enter + tmux attach-session -t canvas + ``` + + + +Detach from tmux with `Ctrl-b`, then `d`. Reattach later with `tmux attach-session -t canvas`. + +## 5. Choose an Access Method + +### Option A: SSH Tunnel + +Use an SSH tunnel when you only need personal access and do not want to expose a public URL. + +On your laptop: + +```bash +ssh -L 8000:127.0.0.1:8000 user@your-vm +``` + +Then use `http://localhost:8000` as the backend URL in **Manage Backends**. + +### Option B: ngrok Without OAuth + +Use ngrok without OAuth only for temporary testing or personal access. Keep `--public` enabled and use a strong `LOCAL_BACKEND_API_KEY`. + +On the VM, in a second terminal or tmux pane: + +```bash +ngrok http 8000 +``` + +Use the `https://...ngrok-free.app` forwarding URL: + +- Backend-only mode: enter it as the **Host / Base URL** in **Manage Backends**. +- Full Canvas mode: open it directly in your browser. + +### Option C: ngrok With Google OAuth + +Use ngrok OAuth with **full Canvas** deployments when the ngrok URL may be reachable by a team or a broader audience. OAuth is an additional gate in front of Agent Canvas; it does not replace `LOCAL_BACKEND_API_KEY`. + +For backend-only deployments, use ngrok without OAuth and keep `--public` enabled. OAuth is best suited to the full Canvas URL where the UI and backend share the same origin. + +Create `~/policy.yml`, replacing `openhands.dev` with your allowed Google Workspace domain: + +```yaml +on_http_request: + # Require Google OAuth login. + - actions: + - type: oauth + config: + provider: google + + # Deny anyone outside the allowed domain. + - expressions: + - "!actions.ngrok.oauth.identity.email.endsWith('@openhands.dev')" + actions: + - type: deny + config: + status_code: 403 +``` + +Start ngrok with the traffic policy: + +```bash +ngrok http 8000 --traffic-policy-file ~/policy.yml +``` + +To run full Canvas and ngrok side by side in tmux: + +```bash +tmux new-session -d -s canvas +tmux send-keys -t canvas 'source ~/.agent-canvas.env && agent-canvas --public' Enter +tmux split-window -h -t canvas +tmux send-keys -t canvas 'ngrok http 8000 --traffic-policy-file ~/policy.yml' Enter +tmux attach-session -t canvas +``` + +### Option D: Reverse Proxy With TLS + +Use a reverse proxy when you need a stable domain instead of an ngrok URL. Point a domain at the VM, proxy it to `127.0.0.1:8000`, and terminate TLS at the proxy. + +On Ubuntu, install nginx and Certbot: + +```bash +sudo apt-get install -y nginx certbot python3-certbot-nginx +``` + +Create `/etc/nginx/sites-available/canvas.example.com`, replacing `canvas.example.com` with your domain: + +```nginx +server { + listen 80; + listen [::]:80; + server_name canvas.example.com; + + location /.well-known/acme-challenge/ { + root /var/www/html; + } + + location / { + proxy_pass http://127.0.0.1:8000; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # WebSocket / SSE support for live agent events. + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_read_timeout 3600s; + proxy_send_timeout 3600s; + } +} +``` + +Enable the site and issue a certificate: + +```bash +sudo ln -sf /etc/nginx/sites-available/canvas.example.com \ + /etc/nginx/sites-enabled/canvas.example.com +sudo nginx -t +sudo systemctl reload nginx + +sudo certbot --nginx -d canvas.example.com \ + --non-interactive --agree-tos \ + --email you@example.com \ + --redirect +``` + +Use `https://canvas.example.com` as the URL for either the remote backend entry or the full Canvas UI. + +## Security Checklist + +Before exposing Agent Canvas beyond an SSH tunnel: + +1. **Run with `--public`** and set a strong `LOCAL_BACKEND_API_KEY`. +2. **Restrict network access** with a firewall, VPN, ngrok OAuth, or an identity-aware proxy. +3. **Use HTTPS** for any internet-reachable URL. +4. **Limit who can SSH to the VM** and keep the OS patched. +5. **Protect the VM filesystem** because it stores settings, secrets, conversations, and working copies. +6. **Rotate keys** if an ngrok URL, API key, or VM login is shared too broadly. + +## Related Guides + +- [Install](/openhands/usage/agent-canvas/setup) +- [Connect and Manage Backends](/openhands/usage/agent-canvas/backends) +- [Local Backend](/openhands/usage/agent-canvas/backend-setup/local) +- [Docker Backend](/openhands/usage/agent-canvas/backend-setup/docker) +- [Cloud Backend](/openhands/usage/agent-canvas/backend-setup/cloud) + +### Backends +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/backends.md + +A **backend** is an [agent server](/sdk/guides/agent-server/overview#what-is-a-remote-agent-server) and the workspace it operates in. All conversations, settings, and automations run against whichever backend is currently selected. + +## Connecting to a Backend + +Any Agent Canvas frontend can connect to any Agent Canvas backend. Use the backend switcher in the UI to open **Manage Backends**, where you can add, edit, or remove entries. Each entry stores a display name, host URL, and an API key for authentication. + +Settings, LLM configuration, MCP servers, and automations are all scoped to the active backend — switching backends switches all of these. + +## Recommended Setups + +| Setup | When to use | How | +|-------|-------------|-----| +| **Default local** | Quick local work on your machine | Run `agent-canvas` — a local backend is created automatically | +| **Backend-only (local)** | Multiple projects, or separate frontend and backend processes | Run `agent-canvas --backend-only` (optionally on different ports), connect with `--frontend-only`. See [Local Backend](/openhands/usage/agent-canvas/backend-setup/local). | +| **Self-hosted VM** | Always-on server, more powerful hardware, team-shared access, or a full self-hosted Canvas | Run `agent-canvas --backend-only --public` for backend-only mode, or `agent-canvas --public` for the full UI and backend. Expose it with SSH, ngrok, or a reverse proxy. See [VM / Self-Hosted Installation](/openhands/usage/agent-canvas/backend-setup/vm). | +| **Cloud** | Managed sandboxes without local resources | Connect to [OpenHands Cloud](/openhands/usage/cloud/openhands-cloud) from **Manage Backends**. See [Cloud Backend](/openhands/usage/agent-canvas/backend-setup/cloud). | + +### Critic +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/critic.md + + + The critic feature is experimental. Configuration options, scoring behavior, + and default models may change as the feature evolves. + + +The critic is an additional evaluation pass that reviews the agent's work and +predicts how likely the task is to succeed. In Agent Canvas, critic results can +appear in the conversation timeline as a success-likelihood score with detected +issue labels. + +Use the critic when you want extra feedback for an OpenHands agent +conversation, or when you want the agent to automatically refine its work after +a low critic score. + + + The default OpenHands-hosted critic is currently free to use. For background + on the critic model and evaluation methodology, read + [SOTA on SWE-Bench Verified with Inference-Time Scaling and Critic Model](https://openhands.dev/blog/sota-on-swe-bench-verified-with-inference-time-scaling-and-critic-model) + and + [A Rubric-Supervised Critic from Sparse Real-World Outcomes](https://arxiv.org/abs/2603.03800). + The critic applies to OpenHands agent conversations. Agent Canvas can also + run third-party ACP agents, but those agents manage their own execution loop + and may not expose the same critic evaluation path. + + +## Prerequisites + +Before enabling the critic: + +1. Configure your active LLM in `Settings > LLM`. +2. Prefer the `OpenHands` LLM provider when you want the default hosted critic + path. +3. Start a new conversation after saving critic settings. Existing + conversations keep the settings they were created with. + +## Enable the Critic + +1. Open `Settings > Verification`. +2. Toggle on `Enable Critic`. +3. Configure the `Critic API Key` field: + - If `OpenHands` is selected as your active LLM provider, leave this field + empty. The critic reuses the active provider's OpenHands Provider LLM Key. + - If you are not using the `OpenHands` LLM provider, paste an OpenHands + Provider LLM Key into `Critic API Key`, or provide the API key required by + your custom critic service. +4. Save the settings. +5. Start a new conversation. + +![Agent Canvas Verification settings with Enable Critic, iterative refinement, critic threshold, and Critic API Key guidance](/openhands/static/img/agent-canvas-critic-settings.png) + +The Critic API Key and the OpenHands Provider LLM Key are the same credential +when you use the default OpenHands-hosted critic service. You can find that key +in the `API Keys` tab of [OpenHands Cloud](https://app.all-hands.dev/settings/api-keys). + +The default hosted critic is free today; the key authenticates access to the +service. + + + A dedicated `Critic API Key` overrides the active LLM key for critic calls + only. Your main LLM configuration continues to use the key from + `Settings > LLM`. + + +## Enable Iterative Refinement + +Iterative refinement lets the critic send the agent back to improve its work +when the predicted success score is too low. + +1. Open `Settings > Verification`. +2. Toggle on `Enable Critic`. +3. Toggle on `Enable Iterative Refinement`. +4. Optionally switch the settings detail view to `Advanced` or `All`. +5. Adjust: + - `Critic Threshold` - the success score required to stop refining. The + default is `0.6`. + - `Max Refinement Iterations` - the maximum number of retry attempts. The + default is `3`. +6. Save the settings and start a new conversation. + +When refinement is enabled, Agent Canvas will let the conversation continue +after a low critic score until the score passes the threshold or the maximum +iteration count is reached. + +## View Critic Results + +When the critic runs, Agent Canvas shows the result below the agent message or +finish action that was evaluated. The compact view shows the predicted success +likelihood score. You can expand the result to inspect detected issue +categories and probabilities, such as incomplete changes, missing validation, +infrastructure issues, or likely user follow-up patterns. + +![Agent Canvas conversation showing a critic success likelihood score below an agent message](/openhands/static/img/agent-canvas-critic-result.png) + +## Troubleshooting + +### Critic Results Do Not Appear + +- Confirm `Enable Critic` is on in `Settings > Verification`. +- Start a new conversation after saving the setting. +- Use the OpenHands agent path. Third-party ACP agents may not expose critic + results. +- Wait until the agent sends a message or finishes a task. With the default + `finish_and_message` mode, the critic does not run after every tool call. + +### Authentication Errors + +If the critic request fails with an API key or authentication error: + +- If `OpenHands` is the active LLM provider, leave `Critic API Key` empty and + confirm the active LLM profile has a saved OpenHands Provider LLM Key. +- If another LLM provider is active, enter an OpenHands Provider LLM Key in + `Critic API Key`. + +### Conversations Become Slow + +- Keep `Critic Mode` set to `finish_and_message` unless you need per-action + feedback. +- Disable `Enable Iterative Refinement` if you only want passive critic scores. +- Lower `Max Refinement Iterations` if repeated refinement loops are too costly. + +## Related Guides + +- [Customize and Settings](/openhands/usage/agent-canvas/customize-and-settings) +- [LLM Profiles and Model Configuration](/openhands/usage/agent-canvas/llm-profiles) +- [OpenHands LLMs](/openhands/usage/llms/openhands-llms) +- [SDK Critic Guide](/sdk/guides/critic) +- [Critic Model Blog Post](https://openhands.dev/blog/sota-on-swe-bench-verified-with-inference-time-scaling-and-critic-model) +- [Critic Research Paper](https://arxiv.org/abs/2603.03800) + +### Customize and Settings +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/customize-and-settings.md + +Agent Canvas separates **Customize** from **Settings**. + +- **Customize** — teach the agent new things. **Skills** give it domain knowledge and specific instructions. **MCP Servers** connect it to external tools and data sources. +- **Settings** — configure how the agent runs. Choose your LLM, store secrets, tune context handling, and set agent behavior. Settings are saved per backend. + +## Customize + +Open the top-level `Customize` area to manage: + +- [Skills](/overview/skills) +- [MCP Servers](/openhands/usage/settings/mcp-settings) + +Use the section navigation inside `Customize` to switch between those pages. + + + MCP configuration lives under `Customize > MCP Servers`, not under `Settings`. + + +## Settings + +The `Settings` area currently includes the following sections: + +| Section | Purpose | +|---------|---------| +| `Agent` | Agent behavior and agent-specific capabilities | +| `LLM` | Provider, model, API key, and profile configuration | +| `Condenser` | Context compression and summarization behavior | +| `Verification` | Approval, critic evaluation, and verification-related behavior | +| `Application` | UI-level preferences and app behavior | +| `Secrets` | Stored secrets used by the active backend | + +On local backends, the `LLM` page also includes an `Available Profiles` area for saved profiles. + +## Configuration Is Per Backend + +Both Customize and Settings are tied to the **active backend**. That means: + +- Changing backends changes which configuration you are editing +- Skills, MCP servers, secrets, and other settings saved for one backend do not automatically apply to every other backend +- The available options can differ depending on backend capabilities + +## Practical Example + +You might use this split like this: + +- Add a GitHub review skill in `Customize > Skills` +- Add a Slack or fetch MCP server in `Customize > MCP Servers` +- Save your preferred model in `Settings > LLM` +- Store tokens in `Settings > Secrets` + +## Related Guides + +- [Connect and Manage Backends](/openhands/usage/agent-canvas/backends) +- [Configure the Critic](/openhands/usage/agent-canvas/critic) +- [Setup a Pre-built Automation](/openhands/usage/agent-canvas/prebuilt-automations) + +### Contributing +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/development.md + +Agent Canvas is open source. To work on it from source: + +1. Clone the repo and install dependencies: + ```bash + git clone https://github.com/OpenHands/agent-canvas.git + cd agent-canvas + npm install + ``` + +2. Start the full development stack: + ```bash + npm run dev + ``` + +For development workflows, environment variables, testing, and advanced configuration, see the [Development Guide](https://github.com/OpenHands/agent-canvas/blob/main/docs/DEVELOPMENT.md) in the repository. + +### First Time Setup +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/first-time-setup.md + +When you open Agent Canvas for the first time, a four-step setup wizard walks you through the core configuration. Each step can be skipped and revisited later from `Settings`. + +## Step 1: Choose Your Agent + +![Agent Canvas first-time setup — Choose your agent screen showing OpenHands, Claude Code, Codex, and Gemini CLI options](/openhands/static/img/agent-canvas-setup-step-1.png) + +Agent Canvas uses the **Agent-Client Protocol (ACP)** to communicate with agents, which means you're not locked into a single provider. + +- **OpenHands** (selected by default) — the general-purpose OpenHands agent, best for coding and exploration. +- **Claude Code** — Anthropic's Claude Code agent. +- **Codex** — OpenAI's Codex agent. +- **Gemini CLI** — Google's Gemini CLI agent. + +Choosing a third-party agent lets you interact with it through the Agent Canvas interface and bring your existing subscriptions from those providers. + +You can change your agent at any time from `Settings`. + +## Step 2: Check Your Backend + +![Agent Canvas first-time setup — Check your backend screen showing a connected local backend at 127.0.0.1:8000](/openhands/static/img/agent-canvas-setup-step-2.png) + +Agent Canvas routes all conversations through an **agent server backend**. By default, it connects to your local machine (`http://127.0.0.1:8000`), which is ideal for working on local projects. + +The setup screen shows your current backend connection status. If the server is running, you'll see a **"You're connected!"** confirmation. + +Each backend entry stores: + +- A display name (e.g. `Local`) +- A host URL +- An optional API key + + + To add remote or cloud backends, or to manage multiple backend connections, see [Connect and Manage Backends](/openhands/usage/agent-canvas/backends). + + +## Step 3: Set Up Your LLM + +![Agent Canvas first-time setup — Set up your LLM screen showing provider and model selection with an API key field](/openhands/static/img/agent-canvas-setup-step-3.png) + +Agent Canvas supports **bring-your-own LLM key**. Select your LLM provider and model, then paste in your API key. + +Available options: + +- **Direct provider keys** — use your own API key from Anthropic, OpenAI, Google, or any other supported provider. +- **OpenHands Cloud** — use an [OpenHands Cloud](https://app.all-hands.dev) API key to access verified models without managing provider accounts directly. Find your API key in the `API Keys` tab of OpenHands Cloud. + +The setup screen defaults to `OpenHands` as the provider and pre-selects a recommended model. Switch the `LLM Provider` dropdown to choose a different provider. + +## Step 4: Start From a Proven Workflow + +![Agent Canvas first-time setup — Say hello screen showing pre-built workflow templates including GitHub PR review copilot, GitHub repository monitor, and Slack standup digest](/openhands/static/img/agent-canvas-setup-step-4.png) + +Agent Canvas is designed as an **automation-centric developer control center**. The final setup step invites you to kick things off with a pre-built workflow template rather than starting from a blank conversation. + +Each template bundles an agent prompt, an implementation sketch, and the MCP connections needed to run it. Pick one to open a pre-filled conversation and finish the details with the agent. + +A recommended starting point is the **[GitHub PR Review Copilot](/openhands/usage/agent-canvas/prebuilt/github-pr-review)**. This automation uses your GitHub MCP connection to poll for new pull requests and run agent review conversations locally — no cloud infrastructure required. + +Other available templates include: + +- **GitHub Repository Monitor** — watch a repository for `@OpenHands` mentions and respond automatically. +- **Slack Standup Digest** — summarize yesterday's Slack activity into an async standup note. + +You can browse all pre-built automations from the `Automate` view at any time. See [Pre-built Automations](/openhands/usage/agent-canvas/prebuilt-automations) for the full list. + +### LLM Profiles and Model Configuration +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/llm-profiles.md + +Agent Canvas supports configuring your LLM provider, model, and credentials from the UI. It also supports saved **LLM profiles**, which make it easier to switch models without re-entering provider settings each time. + +## Where to Configure Models + +Open `Settings > LLM` to: + +- choose a provider +- select or enter a model +- add the required API key +- save reusable LLM profiles + +## Working with LLM Profiles + +LLM profiles are useful when you want different model setups for different tasks, such as: + +- a fast profile for iteration +- a stronger profile for planning or review +- a local model profile for offline experiments + +## Switching Profiles in a Conversation + +You can switch profiles from the chat input with the `/model` command: + +- `/model` — list the saved profiles available to the conversation +- `/model ` — switch to a specific saved profile + +Agent Canvas also shows model-switch events in the conversation timeline so you can see when a profile changed during a task. + + + LLM profiles are fully supported in Agent Canvas and are still rolling out in OpenHands Cloud. If you connect Agent Canvas to a cloud backend, profiles you configure in Agent Canvas may be available there before the same profiles appear in the hosted OpenHands Cloud UI for your account. + + +## Recommended Workflow + +1. Configure a default profile in `Settings > LLM`. +2. Create additional profiles for specific tasks or cost levels. +3. Start a conversation. +4. Use `/model` when you want to switch profiles without leaving the chat. + +## Related Guides + +- [Setup](/openhands/usage/agent-canvas/setup) +- [Customize and Settings](/openhands/usage/agent-canvas/customize-and-settings) +- [LLM Settings](/openhands/usage/settings/llm-settings) + +### Agent Canvas Overview +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/overview.md + + + Agent Canvas is in Beta. Expect the install path, packaging, and some UI details to keep evolving. + + +## Why Agent Canvas + +- **One UI to drive any agent**: run conversations with OpenHands, Claude Code, Codex, or Gemini CLI through the same browser interface. +- **Bring your own LLM**: connect Anthropic, OpenAI, Google, or any OpenAI-compatible provider. Switch models per conversation. +- **Built-in automations**: schedule cron jobs or wire up event-driven workflows against GitHub, Linear, Slack, and custom webhooks. +- **Run it anywhere**: a single `agent-canvas` command starts the full stack locally. Self-host on a VM, or connect to OpenHands Cloud. + +## Key Concepts + +| Concept | What It Means | +|---------|----------------| +| **Agent Canvas** | A UI and backend server for running agents and automations. The `agent-canvas` command starts both together. | +| **Backend** | Any Canvas UI can securely connect to any Canvas backend: running locally, on a remote machine, or on [OpenHands Cloud](/openhands/usage/cloud/openhands-cloud). Register multiple and switch between them. | +| **Conversation** | A single agent session tied to a backend. Each conversation has its own message history, tool calls, and file changes. | +| **Automation** | A workflow that runs on a cron schedule or in response to events from GitHub, Linear, Slack, or custom webhooks. Automations may start agent conversations as needed. | + +## How It Fits with Other OpenHands Products + +- **Agent Canvas**: the recommended browser-based UI for running OpenHands locally or self-hosted. +- **Local GUI (Legacy)**: legacy UI requiring Docker. +- **OpenHands Cloud**: a fully managed version of OpenHands. +- **OpenHands SDK**: the Python framework behind the agent system. + +## Where to Start + +- [Install](/openhands/usage/agent-canvas/setup) — Use the published npm package to run Agent Canvas from your terminal. +- [Connect and Manage Backends](/openhands/usage/agent-canvas/backends) — Switch between local and remote backends. +- [Customize and Settings](/openhands/usage/agent-canvas/customize-and-settings) — Configure skills, MCP servers, and backend-synced settings. +- [Setup a Pre-built Automation](/openhands/usage/agent-canvas/prebuilt-automations) — Get started with a ready-made automation workflow. +- [VM / Self-Hosted Installation](/openhands/usage/agent-canvas/backend-setup/vm) — Run backend-only or full Canvas on a VM and connect remotely. + +### Setup a Pre-built Automation +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/prebuilt-automations.md + +Agent Canvas ships with a set of pre-built automations for the most common agent workflows. Each one is a ready-to-use starting point — pick the one that fits your use case, connect it to the right backend, and you can have an automation running in minutes. + +## Available Pre-built Automations + +| Automation | What It Does | +|------------|-------------| +| [GitHub PR Review Assistant](/openhands/usage/agent-canvas/prebuilt/github-pr-review) | Automatically reviews pull requests and posts feedback as a comment | +| [GitHub Repository Monitor](/openhands/usage/agent-canvas/prebuilt/github-repo-monitor) | Watches a repository for events and triggers agent actions in response | +| [Slack Channel Monitor](/openhands/usage/agent-canvas/prebuilt/slack-channel-monitor) | Listens to a Slack channel and triggers an agent when a message matches a pattern | + +--- + +Every canvas backend includes an automation service, so you can run agents on a schedule or in response to external events. + +## What You Can Do + +In the `Automate` view, you can: + +- Browse existing automations +- Inspect automation configuration and activity +- Enable or disable automations +- Work with recommended automation flows + +## How Creation Flows Usually Start + +The `Automations` view is mainly for browsing and managing automations that already exist. + +In practice, new automation setup often starts in one of two ways: + +- From a conversation, where you ask OpenHands to create an automation for you +- From a recommended automation flow in the `Automations` view + +Visit the Automations Docs have a more [detailed guide on creating automations](/openhands/usage/automations/creating-automations). + +Automations run against the active backend. Use [Manage Backends](/openhands/usage/agent-canvas/backends) to see and switch which backend your automations run on. + +### GitHub PR Review Assistant +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/prebuilt/github-pr-review.md + +Use the GitHub PR Review Assistant when you want Agent Canvas to watch pull requests and have an OpenHands agent review them. + +The setup has two parts: + +- Give the active backend access to GitHub +- Start the pre-built PR review workflow from `Automate` + +## Prerequisites + +Before you start, make sure you have: + +- Agent Canvas installed and running +- An LLM configured for the backend that will run the automation +- Access to create a GitHub token for the repository you want to review +- Access to install MCP servers and save secrets in Agent Canvas + +If you are new to Agent Canvas, start with [Install](/openhands/usage/agent-canvas/setup) and [First-Time Setup](/openhands/usage/agent-canvas/first-time-setup). + +## Create a GitHub Access Token + +1. Go to [GitHub Developer Settings](https://github.com/settings/tokens). +2. Click `Generate new token`. +3. Prefer a fine-grained personal access token if your organization supports it. +4. Give the token a clear name, such as `Agent Canvas PR Reviewer`. +5. Select repository access: + - Choose `Only select repositories` for the safest setup. + - Choose `All repositories` only if the automation needs broad access. +6. Set an expiration date that matches your team's security policy. + +## Add Repository Permissions + +In the token setup screen, grant the permissions the reviewer needs. + +For a PR review automation, use: + +| Permission | Access | +|------------|--------| +| `Contents` | Read and write | +| `Issues` | Read and write | +| `Pull requests` | Read and write | +| `Metadata` | Read-only | +| `Actions` | Read-only, if the automation should inspect CI results | +| `Checks` | Read-only, if the automation should inspect check runs | + +Then click `Generate token` and copy the token immediately. + + + GitHub only shows the token once. Store it somewhere secure until you finish configuring Agent Canvas. + + +## Add the GitHub MCP Server + +The GitHub MCP server gives the agent tools for reading repositories, inspecting pull requests, and posting review output. + +1. In Agent Canvas, check the backend switcher in the bottom-left corner. +2. Make sure the active backend is the backend where you want the PR review automation to run. +3. Open `Customize`. +4. Open `MCP Servers`. +5. Select `GitHub` from the MCP library. +6. Paste the GitHub token you created earlier. +7. Make sure the secret-creation toggle is on so Agent Canvas creates the token secret automatically when you save the MCP server configuration. +8. Save the MCP server configuration. + +## Start the PR Review Workflow + +1. Open `Automate` in the left navigation. +2. Find `Start from a proven workflow`. +3. Choose the GitHub PR review workflow. +4. Agent Canvas opens a new conversation with a prefilled setup prompt. +5. Send the prompt as-is, or edit it first if you already know what you want. + +After you send the prompt, the agent starts a setup conversation. It uses the preconfigured skills and GitHub access to interview you, clarify the review workflow, and create the automation. + +## Customize the Review + +You do not need to know every detail before sending the prefilled prompt. The agent will ask follow-up questions to clarify: + +- The repository owner and name +- Which pull requests to review +- Whether the agent should post a single summary comment or detailed inline feedback +- Whether the agent should inspect CI results before commenting +- Any files, directories, or checks the reviewer should ignore + +You can edit the prefilled prompt before sending it if you want to provide any of those details up front. + +## Verify the Automation + +After the automation is created: + +1. Open `Automate`. +2. Confirm the new automation appears in the list. +3. Open the automation details and check that it is enabled. +4. Trigger or wait for a matching pull request event. +5. Confirm that the agent run appears and that the review is posted to GitHub. + +## Related Guides + +- [GitHub Repository Monitor](/openhands/usage/agent-canvas/prebuilt/github-repo-monitor) +- [Setup a Pre-built Automation](/openhands/usage/agent-canvas/prebuilt-automations) +- [Customize and Settings](/openhands/usage/agent-canvas/customize-and-settings) + +### GitHub Repository Monitor +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/prebuilt/github-repo-monitor.md + +Use the GitHub Repository Monitor when you want Agent Canvas to watch a repository and trigger an OpenHands agent when matching activity happens. + +Common examples include: + +- Monitoring new issues and pull requests +- Watching failed CI runs +- Checking for dependency or release activity +- Creating follow-up work when a repository changes + +## Prerequisites + +Before you start, make sure you have: + +- Agent Canvas installed and running +- An LLM configured for the backend that will run the automation +- Access to create a GitHub token for the repository you want to monitor +- Access to install MCP servers and save secrets in Agent Canvas + +If you are new to Agent Canvas, start with [Install](/openhands/usage/agent-canvas/setup) and [First-Time Setup](/openhands/usage/agent-canvas/first-time-setup). + +## Create a GitHub Access Token + +1. Go to [GitHub Developer Settings](https://github.com/settings/tokens). +2. Click `Generate new token`. +3. Prefer a fine-grained personal access token if your organization supports it. +4. Give the token a clear name, such as `Agent Canvas Repo Monitor`. +5. Select repository access: + - Choose `Only select repositories` for the safest setup. + - Choose `All repositories` only if the automation needs broad access. +6. Set an expiration date that matches your team's security policy. + +## Add Repository Permissions + +In the token setup screen, grant only the permissions your monitor needs. + +For most repository monitors, start with: + +| Permission | Access | +|------------|--------| +| `Contents` | Read-only, or read and write if the agent will open changes | +| `Issues` | Read and write if the agent will triage or comment on issues | +| `Pull requests` | Read and write if the agent will inspect or comment on pull requests | +| `Metadata` | Read-only | +| `Actions` | Read-only, if the automation should inspect workflow runs | +| `Checks` | Read-only, if the automation should inspect check runs | + +Then click `Generate token` and copy the token immediately. + + + If you change token permissions later, you may need to update the token or create a new one. + + +## Add the GitHub MCP Server + +The GitHub MCP server gives the agent tools for reading repository state and taking GitHub actions. + +1. In Agent Canvas, check the backend switcher in the bottom-left corner. +2. Make sure the active backend is the backend where you want the repository monitor to run. +3. Open `Customize`. +4. Open `MCP Servers`. +5. Select `GitHub` from the MCP library. +6. Paste the GitHub token you created earlier. +7. Make sure the secret-creation toggle is on so Agent Canvas creates the token secret automatically when you save the MCP server configuration. +8. Save the MCP server configuration. + +## Start the Repository Monitor Workflow + +1. Open `Automate` in the left navigation. +2. Find `Start from a proven workflow`. +3. Choose the GitHub repository monitor workflow. +4. Agent Canvas opens a new conversation with a prefilled setup prompt. +5. Send the prompt as-is, or edit it first if you already know what you want. + +After you send the prompt, the agent starts a setup conversation. It uses the preconfigured skills and GitHub access to interview you, clarify the monitoring workflow, and create the automation. + +## Customize the Monitor + +You do not need to know every detail before sending the prefilled prompt. The agent will ask follow-up questions to clarify: + +- The repository owner and name +- The events or conditions the monitor should watch +- How often the automation should check the repository, if it is schedule-based +- What the agent should do when it finds a match +- Where the agent should report results, such as a GitHub comment or Slack channel + +You can edit the prefilled prompt before sending it if you want to provide any of those details up front. + +For example, you can ask the monitor to watch for failed workflow runs, summarize the failure, and open a pull request when the fix is straightforward. + +## Verify the Automation + +After the automation is created: + +1. Open `Automate`. +2. Confirm the new automation appears in the list. +3. Open the automation details and check that it is enabled. +4. Trigger or wait for matching repository activity. +5. Confirm that the agent run appears and performs the action you requested. + +## Related Guides + +- [GitHub PR Review Assistant](/openhands/usage/agent-canvas/prebuilt/github-pr-review) +- [Setup a Pre-built Automation](/openhands/usage/agent-canvas/prebuilt-automations) +- [Customize and Settings](/openhands/usage/agent-canvas/customize-and-settings) + +### Slack Channel Monitor +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/prebuilt/slack-channel-monitor.md + +Use the Slack Channel Monitor when you want Agent Canvas to watch a Slack channel and trigger an OpenHands agent when a message matches your instructions. + +Common examples include: + +- Responding when someone mentions a support keyword +- Turning bug reports into GitHub issues +- Summarizing incidents from an alerts channel +- Running a repository task from a Slack request + +## Prerequisites + +Before you start, make sure you have: + +- Agent Canvas installed and running +- An LLM configured for the backend that will run the automation +- Permission to create and install a Slack app in your workspace +- Access to install MCP servers and save secrets in Agent Canvas + +If you are new to Agent Canvas, start with [Install](/openhands/usage/agent-canvas/setup) and [First-Time Setup](/openhands/usage/agent-canvas/first-time-setup). + +## Create the Slack App + +1. Go to the [Slack API dashboard](https://api.slack.com/apps). +2. Click `Create New App`. +3. Select `From scratch`. +4. Enter an app name, such as `OpenHands`. +5. Choose the workspace where you want to install the bot. +6. Click `Create App`. + +## Add Bot Token Scopes + +Before Slack gives you a bot token, you need to define what the bot is allowed to do. + +1. In the Slack app settings, open `OAuth & Permissions`. +2. Scroll to `Scopes`. +3. Under `Bot Token Scopes`, click `Add an OAuth Scope`. +4. Add the scopes required by the Slack MCP server and your monitor. + +For a channel monitor, add these bot token scopes: + +| Scope | Purpose | +|-------|---------| +| `app_mentions:read` | View messages that directly mention the app in conversations it belongs to | +| `channels:read` | List and read public channel metadata | +| `channels:history` | Read messages from public channels | +| `chat:write` | Send messages as the app | +| `emoji:read` | View custom emoji in the workspace | +| `groups:history` | Read messages from private channels the app has been added to | +| `reactions:read` | View emoji reactions and associated message content | +| `reactions:write` | Add and edit emoji reactions | +| `users:read` | Resolve Slack users and profiles | + + + Slack may require you to reinstall the app after changing scopes. + + +## Install the App and Copy the Bot Token + +1. Stay on the `OAuth & Permissions` page. +2. Click `Install to Workspace`. +3. Review the requested permissions. +4. Click `Allow`. +5. Copy the `Bot User OAuth Token` from the `OAuth Tokens` section. + +## Invite the Bot to Channels + +The bot does not automatically join channels. + +Invite it to every channel you want the automation to monitor. The Agent Canvas backend can only watch channels the bot can access. + +## Find Your Slack Workspace ID + +The Slack MCP server also needs your workspace ID. + +You can find it from your Slack URL or workspace settings. See Slack's guide to [locating your Slack URL or ID](https://slack.com/help/articles/221769328-Locate-your-Slack-URL-or-ID). + +## Add the Slack MCP Server + +The Slack MCP server gives the agent tools for reading Slack channel activity and posting responses. + +1. In Agent Canvas, check the backend switcher in the bottom-left corner. +2. Make sure the active backend is the backend where you want the Slack monitor to run. +3. Open `Customize`. +4. Open `MCP Servers`. +5. Select `Slack` from the MCP library. +6. Paste the bot token. +7. Enter your Slack workspace ID. +8. Make sure the secret-creation toggle is on so Agent Canvas creates the bot token secret automatically when you save the MCP server configuration. +9. Save the MCP server configuration. + +## Start the Slack Channel Monitor Workflow + +1. Open `Automate` in the left navigation. +2. Find `Start from a proven workflow`. +3. Choose the Slack channel monitor workflow. +4. Agent Canvas opens a new conversation with a prefilled setup prompt. +5. Send the prompt as-is, or edit it first if you already know what you want. + +After you send the prompt, the agent starts a setup conversation. It uses the preconfigured skills and Slack access to interview you, clarify the channel monitor, and create the automation. + +## Customize the Monitor + +You do not need to know every detail before sending the prefilled prompt. The agent will ask follow-up questions to clarify: + +- The Slack channel or channels to monitor +- The message pattern, keyword, or mention that should trigger the agent +- What the agent should do when a message matches +- Whether the agent should reply in Slack +- Any GitHub repository or external service the agent should use + + + + If you want the automation to watch for `@your-bot-name`, tell the agent to watch for Slack bot mentions as well as the trigger phrases you set. That way, it can respond when someone mentions the bot directly, not just when a specific keyword appears. + + +You can edit the prefilled prompt before sending it if you want to provide any of those details up front. + +For example, you can ask the tell the agent to configure the automation to watch an #alerts channel, summarize new incidents, and create a GitHub issue when a message includes a production error. + + +## Verify the Automation + +After the automation is created: + +1. Open `Automate`. +2. Confirm the new automation appears in the list. +3. Open the automation details and check that it is enabled. +4. Post a test message in a channel the bot has joined. +5. Confirm that the agent run appears and performs the action you requested. + +## Related Guides + +- [GitHub Repository Monitor](/openhands/usage/agent-canvas/prebuilt/github-repo-monitor) +- [Setup a Pre-built Automation](/openhands/usage/agent-canvas/prebuilt-automations) +- [Customize and Settings](/openhands/usage/agent-canvas/customize-and-settings) + +### Install +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/setup.md + + + Agent Canvas starts an agent server on the machine where you run it. Treat that machine as trusted infrastructure and review the guidance in [VM / Self-Hosted Installation](/openhands/usage/agent-canvas/backend-setup/vm) before exposing it to a network you do not control. + + + + + **Prerequisites:** [Node.js](https://nodejs.org/en/download) 22.12 or later, `npm`, and [`uv`](https://docs.astral.sh/uv/getting-started/installation/). + + **Install:** + ```bash + npm install -g @openhands/agent-canvas + ``` + + **Run:** + ```bash + agent-canvas + ``` + + By default, Agent Canvas starts on `http://localhost:8000`. + + ### CLI Flags + + | Flag | Description | + |------|-------------| + | `-p`, `--port ` | Set the ingress port (default `8000`) | + | `--public` | Enable public mode — requires `LOCAL_BACKEND_API_KEY`. The key is **not** injected into the frontend; users must enter it when the UI loads. Use this for any deployment reachable by others. See [VM / Self-Hosted Installation](/openhands/usage/agent-canvas/backend-setup/vm). | + | `--backend-only` | Start only the backend behind ingress (no frontend). Use this to run a headless backend on a VM or server. | + | `--frontend-only` | Start only the static frontend behind ingress (no agent server or automation). Use this to point a local UI at a remote backend. | + | `-v`, `--version` | Show the version number | + | `--info` | Show the version and default stack configuration (agent server version, ports, etc.) | + | `-h`, `--help` | Show the built-in help output | + + ### Environment Variables + + | Variable | Purpose | + |----------|---------| + | `LOCAL_BACKEND_API_KEY` | API key for the server. Required in `--public` mode; optional otherwise (auto-generated and persisted across restarts). | + | `OH_SECRET_KEY` | Secret used to protect stored settings and secrets | + | `OH_AGENT_SERVER_VERSION` | Pin a specific agent server version (e.g. `0.1.0`) | + + + **Prerequisites:** [Docker](https://docs.docker.com/get-docker/) (Docker Desktop on macOS/Windows, or Docker Engine on Linux). + + A Docker image is available that sandboxes the entire Agent Canvas stack. Mount your project files and a persistence directory for settings, secrets, and conversation history. + + Create a host directory for your projects (the agent can access any folder under this path) and run the container: + + **macOS / Linux:** + ```bash + mkdir -p ~/projects ~/.openhands + + docker run -it --rm \ + -p 8000:8000 \ + -v ~/.openhands:/home/openhands/.openhands \ + -v ~/projects:/projects \ + ghcr.io/openhands/agent-canvas:latest + ``` + + **Windows (PowerShell):** + ```powershell + New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.openhands", "$env:USERPROFILE\projects" | Out-Null + + docker run -it --rm ` + -p 8000:8000 ` + -v "$($env:USERPROFILE)\.openhands:/home/openhands/.openhands" ` + -v "$($env:USERPROFILE)\projects:/projects" ` + ghcr.io/openhands/agent-canvas:latest + ``` + + + On Windows, Docker Desktop must be installed and running. PowerShell uses backticks (`` ` ``) for line continuation instead of backslashes. + + + ### Environment Variables + + Configuration is passed via `-e` flags on `docker run`: + + | Variable | Purpose | + |----------|---------| + | `PORT` | Ingress port inside the container (default `8000`). Map it with `-p :`. | + | `LOCAL_BACKEND_API_KEY` | API key for the server. Auto-generated and persisted if not set. | + | `OH_SECRET_KEY` | Secret used to protect stored settings and secrets | + + + + + If you want to clone the repository, run custom dev modes, or configure Vite-specific environment variables, use the [Contribute / Development guide](/openhands/usage/agent-canvas/development) instead. + + +## First Steps After Launch + +After the UI opens: + +1. Confirm the default local backend is healthy. +2. Open `Settings > LLM` and configure a provider, model, and API key. +3. Open `Customize` if you want to add skills or MCP servers. +4. Return to the home screen and enter a prompt to start your first conversation. +5. If you want the conversation tied to a local folder, choose `Open Workspace` first. + +## Next Steps + +- [Connect and Manage Backends](/openhands/usage/agent-canvas/backends) +- [LLM Profiles and Model Configuration](/openhands/usage/agent-canvas/llm-profiles) +- [Customize and Settings](/openhands/usage/agent-canvas/customize-and-settings) + +### Troubleshooting +Source: https://docs.openhands.dev/openhands/usage/agent-canvas/troubleshooting.md + +Use this page for the most common Agent Canvas problems. + +## Command Not Found + +If `agent-canvas` is not available after installation: + +- confirm the package installed successfully with `npm install -g @openhands/agent-canvas` +- make sure your npm global bin directory is on your `PATH` +- run `agent-canvas --help` to confirm the binary resolves correctly + +## Missing `uv` + +Agent Canvas relies on `uv` to run the local agent server stack. + +If startup fails because `uv` or `uvx` is missing, install it from the official guide: + +- [uv installation guide](https://docs.astral.sh/uv/getting-started/installation/) + +## Port Already in Use + +Agent Canvas listens on port `8000` by default. If that port is busy, start it on another one: + +```bash +agent-canvas --port 3000 +``` + +## Backend Is Unreachable + +If Agent Canvas cannot talk to the active backend: + +- open `Manage Backends` +- verify the backend host or base URL +- verify the API key if the backend requires one +- switch to another backend to confirm the issue is backend-specific + +## LLM Profiles Do Not Match OpenHands Cloud + +Agent Canvas currently has fuller support for LLM profiles than the hosted OpenHands Cloud UI. + +If profiles appear in Agent Canvas but not in OpenHands Cloud directly, that can be expected while the Cloud rollout is still in progress. + +## MCP Settings Are Missing + +MCP configuration does not live under `Settings`. + +Open the top-level `Customize` area, then go to `MCP Servers`. + +## Automation Features Are Unavailable + +If the `Automations` view shows an unavailable or unhealthy state, the active backend may not have a working automation service. + +Start with the default local backend to confirm the UI works, then debug the remote backend separately. + +## Get Help + +If you are still stuck: + +- [Join the OpenHands Slack community](https://openhands.dev/joinslack) +- [Open an issue in the Agent Canvas repository](https://github.com/OpenHands/agent-canvas/issues) +- [Browse the Agent Canvas source](https://github.com/OpenHands/agent-canvas) + ### Main Agent and Capabilities Source: https://docs.openhands.dev/openhands/usage/agents.md @@ -28947,11 +30871,78 @@ Source: https://docs.openhands.dev/openhands/usage/automations/event-automations Event-based automations run when something happens—a PR is opened, an issue is commented on, or a webhook fires—instead of on a schedule. This is ideal for responsive workflows like auto-reviewing PRs, triaging issues, or reacting to external service events. +## Prerequisites for GitHub Event Automations + +GitHub event automations require some one-time setup before events will flow. If any step is missing, automations will appear to work (manual triggers succeed) but GitHub events will silently never arrive. + +### 1. Install the OpenHands GitHub App + +The OpenHands GitHub App must be installed on the GitHub organization that owns the repositories you want to monitor. Install it from your [GitHub integration settings](/openhands/usage/cloud/github-installation). The app needs access to the repositories that will generate events. + +### 2. Create an OpenHands Team Organization + +If you're working with repositories owned by a GitHub organization (e.g., `myorg/my-repo`), you need an OpenHands **team organization** — not just a personal account. GitHub events for org repos are routed to team orgs, not personal orgs. + +If you don't already have one, create a team organization — see [What Are Organizations](/openhands/usage/cloud/organizations/overview#what-are-organizations) for details and how to get started. + +### 3. Claim Your GitHub Organization + + +**This is the most commonly missed step.** Without it, GitHub events have nowhere to be routed and will be silently dropped. + + +Your OpenHands team org must **claim** the GitHub organization to establish the link between GitHub webhooks and your OpenHands org. Claiming tells the event router: _"Events for repos in this GitHub org should go to this OpenHands team org."_ + +To claim a GitHub org: + +1. Switch to your team org using the org switcher in the sidebar +2. Go to **Organization Settings** +3. In the **Git Conversation Routing** section, find your GitHub org +4. Click **Claim** + +You must be an **Owner** of the OpenHands team org and have **admin access** to the GitHub org to complete the claim. See [Claiming Git Organizations](/openhands/usage/cloud/organizations/settings#claiming-git-organizations) for full details. + + +Each GitHub organization can only be claimed by one OpenHands team org. If another team has already claimed it, coordinate with them or contact support. + + +### 4. Create the Automation Under the Team Org + +Make sure you are switched to the **team org** (not your personal org) when creating the automation. The automation must live in the same org that claimed the GitHub organization — otherwise events won't match. + +### 5. (Optional) Add Service Accounts to the Team Org + +If you're using a service account (like a bot account) to create or own automations, that account must be a **member of the team org**. Invite them from the [Organization Members](/openhands/usage/cloud/organizations/managing-members) page. + +### Troubleshooting + +If your automation doesn't trigger on GitHub events: + + + + The OpenHands GitHub App must be installed on the GitHub organization that owns your repositories. Go to [GitHub integration settings](/openhands/usage/cloud/github-installation) and verify it is installed with access to the relevant repos. Without this, no webhook events are sent to OpenHands. + + + The most common cause. Go to **Organization Settings → Git Conversation Routing** and check if your GitHub org shows as claimed. If not, click **Claim**. See [Claiming Git Organizations](/openhands/usage/cloud/organizations/settings#claiming-git-organizations). + + + GitHub events for org repos are routed to the **team org** that claimed the GitHub org. If you created the automation under your personal org, events will never reach it. Switch to the team org and recreate the automation. + + + Double-check that the event type (e.g., `pull_request.labeled`) and filter expression match the action you're testing. Use wildcards like `pull_request.*` to match all actions during debugging. + + + Verify the automation is enabled. You can check via the automations list or by asking OpenHands to list your automations. + + + +--- + ## Built-In vs. Custom Integrations | Type | Setup | Best For | |------|-------|----------| -| **Built-in (GitHub)** | None—just create the automation | PR reviews, issue triage, push-triggered tasks | +| **Built-in (GitHub)** | One-time org setup ([see above](#prerequisites-for-github-event-automations)), then create the automation | PR reviews, issue triage, push-triggered tasks | | **Custom Webhooks** | Register webhook first, then create automation | Linear, Stripe, Slack, and other services | ## GitHub Events (Built-In) @@ -29000,25 +30991,30 @@ Use wildcards like `pull_request.*` to match all actions for an event type. Filters let you narrow which events trigger your automation. They use [JMESPath expressions](https://jmespath.org/) to match fields in the event payload—so you can trigger only on specific labels, users, branches, or other conditions. + +OpenHands extends standard JMESPath with custom functions including `icontains` (case-insensitive string match) and `glob` (wildcard path matching). It also supports `!` (negation), `&&` (AND), and `||` (OR) as boolean operators. These extensions are not part of the [JMESPath specification](https://jmespath.org/specification.html). + + **Common filter patterns:** -```javascript -// Match a specific label +``` contains(pull_request.labels[].name, 'openhands') -// Case-insensitive mention in comment icontains(comment.body, '@openhands') -// Match repos in your org glob(repository.full_name, 'myorg/*') -// Push to main branch only ref == 'refs/heads/main' -// Combine conditions glob(repository.full_name, 'myorg/*') && contains(pull_request.labels[].name, 'bug') ``` +- `contains(...)` — match a specific label +- `icontains(...)` — case-insensitive mention in a comment body +- `glob(...)` — match repos in your org with wildcards +- `==` — exact match (e.g., push to main branch only) +- `&&` — combine multiple conditions + --- ## Custom Webhooks @@ -29132,12 +31128,12 @@ When registering any custom webhook, these parameters define how OpenHands proce These are example configurations for popular services. **Always verify with each service's webhook documentation**, as signature headers and payload formats may change. -| Service | Signature Header | Event Key | -|---------|-----------------|-----------| -| Linear | `Linear-Signature` | `type` | -| Stripe | `Stripe-Signature` | `type` | -| Slack | `X-Slack-Signature` | `type` | -| Twilio | `X-Twilio-Signature` | `type` | +| Service | Signature Header | Event Key | Notes | +|---------|-----------------|-----------|-------| +| Linear | `Linear-Signature` | `type` | | +| Stripe | `Stripe-Signature` | `type` | Uses a custom `t=timestamp,v1=signature` format — verify compatibility | +| Slack | `X-Slack-Signature` | `type` | | +| Twilio | `X-Twilio-Signature` | `type` | Uses HMAC-SHA1 of request URL + params — verify compatibility | --- @@ -29363,7 +31359,7 @@ Each use case has a ready-to-use automation prompt. Click a card to see the full Functionally test PR changes by exercising the software as a real user would. @@ -30730,6 +32726,21 @@ These variables correspond to the `[security]` section in `config.toml`: ## Integration Variables +### Git Provider Access +| Environment Variable | Type | Default | Description | +|---------------------|------|---------|-------------| +| `ALLOW_INSECURE_GIT_ACCESS` | boolean | `false` | Allow OpenHands to connect to git providers over plain HTTP. Set this only for trusted local or internal git providers (such as Gitea/Forgejo) where HTTPS is not available. | + + + `ALLOW_INSECURE_GIT_ACCESS=true` permits insecure HTTP connections to git providers. Only enable it for trusted local or internal networks that you control. Do not use it for public or untrusted git providers. + + +When running OpenHands with Docker, set this on the OpenHands server container: + +```bash +docker run -e ALLOW_INSECURE_GIT_ACCESS=true openhands/openhands +``` + ### GitHub Integration | Environment Variable | Type | Default | Description | |---------------------|------|---------|-------------| @@ -32761,23 +34772,23 @@ then switch back to a stronger model for planning, debugging, and review. ### Best Cloud Models by Family -| Family | Recommended Model | Model String | OpenHands Index Average | Notes | -|--------|-------------------|--------------|-------------------------|-------| -| Claude | [Claude Opus 4.7](https://github.com/OpenHands/openhands-index-results/tree/main/results/claude-opus-4-7) | `anthropic/claude-opus-4-7` | 68.2 | Best Claude-series result in the OpenHands Index. Use it for complex, long-running software work. Claude Opus 4.6 is close behind at 66.7. | -| GPT | [GPT-5.5](https://github.com/OpenHands/openhands-index-results/tree/main/results/GPT-5.5) | `openai/gpt-5.5` | 65.9 | Best GPT-series result in the OpenHands Index. GPT-5.4 is close behind at 64.3. | -| Gemini | [Gemini 3.1 Pro](https://github.com/OpenHands/openhands-index-results/tree/main/results/Gemini-3.1-Pro) | `gemini/gemini-3.1-pro-preview` | 57.0 | Best Gemini-series result in the OpenHands Index. Use Gemini 3 Flash when cost or latency is more important than top accuracy. | +| Family | Recommended Model | Model String | OpenHands Index Average | +|--------|-------------------|--------------|-------------------------| +| Claude | [claude-opus-4-8](https://github.com/OpenHands/openhands-index-results/tree/main/results/claude-opus-4-8) | Not yet listed | 71.9 | +| GPT | [GPT-5.5](https://github.com/OpenHands/openhands-index-results/tree/main/results/GPT-5.5) | `openai/gpt-5.5` | 65.9 | +| Gemini | [Gemini-3.1-Pro](https://github.com/OpenHands/openhands-index-results/tree/main/results/Gemini-3.1-Pro) | `gemini/gemini-3.1-pro-preview` | 57.0 | ### Strong Open / Open-Weight Models These open or open-weight models have good OpenHands Index scores or are recommended for local OpenHands setups: -| Model | Suggested Model String | OpenHands Index Average | Notes | -|-------|------------------------|-------------------------|-------| -| [GLM-5.1](https://github.com/OpenHands/openhands-index-results/tree/main/results/GLM-5.1) | `openrouter/z-ai/glm-5.1` | 58.2 | Strongest open-weight result currently listed in the OpenHands Index. | -| [Kimi-K2.6](https://github.com/OpenHands/openhands-index-results/tree/main/results/Kimi-K2.6) | `openrouter/moonshotai/kimi-k2.6` | 57.1 | Strong open-weight option, especially for coding and information-gathering tasks. | -| [DeepSeek-V4-Pro](https://github.com/OpenHands/openhands-index-results/tree/main/results/DeepSeek-V4-Pro) | `openrouter/deepseek/deepseek-v4-pro` | 51.3 | Strong coding and test-generation scores; current Index entry covers three benchmarks. | -| [MiniMax-M2.7](https://github.com/OpenHands/openhands-index-results/tree/main/results/MiniMax-M2.7) | `openrouter/minimax/minimax-m2.7` | 43.4 | Recommended as a lower-cost open-weight option with strong SWE-bench and SWT-bench scores. Also available from MiniMax-compatible OpenAI endpoints as `openai/MiniMax-M2.7`. | -| [Qwen3.6-35B-A3B](https://huggingface.co/Qwen/Qwen3.6-35B-A3B) | `openai/Qwen3.6-35B-A3B` for local OpenAI-compatible servers, or `openrouter/qwen/qwen3.6-35b-a3b` through OpenRouter | Not yet listed | Recommended local / self-hosted model for OpenHands. It is open-weight, supports a large context window, and is featured in the [local LLM guide](/openhands/usage/llms/local-llms). | +| Model | Suggested Model String | OpenHands Index Average | +|-------|------------------------|-------------------------| +| [GLM-5.1](https://github.com/OpenHands/openhands-index-results/tree/main/results/GLM-5.1) | `openrouter/z-ai/glm-5.1` | 58.2 | +| [Kimi-K2.6](https://github.com/OpenHands/openhands-index-results/tree/main/results/Kimi-K2.6) | `openrouter/moonshotai/kimi-k2.6` | 57.1 | +| [GLM-5](https://github.com/OpenHands/openhands-index-results/tree/main/results/GLM-5) | `openrouter/z-ai/glm-5` | 49.4 | +| [Kimi-K2.5](https://github.com/OpenHands/openhands-index-results/tree/main/results/Kimi-K2.5) | `openrouter/moonshotai/kimi-k2.5` | 49.2 | +| [DeepSeek-V3.2-Reasoner](https://github.com/OpenHands/openhands-index-results/tree/main/results/DeepSeek-V3.2-Reasoner) | `openrouter/deepseek/deepseek-v3.2-reasoner` | 45.7 | Hosted model strings can vary by provider and region. If a model string is not accepted, check the provider console and @@ -32943,6 +34954,18 @@ Download and install the LM Studio desktop app from [lmstudio.ai](https://lmstud ![image](./screenshots/06_lm_studio_start_server.png) + +**Linux users:** By default, LM Studio only listens on `127.0.0.1` (localhost). If OpenHands runs inside a Docker container, it cannot reach `127.0.0.1` on the host — even with `--add-host host.docker.internal:host-gateway`. + +To fix this, enable **"Serve on Local Network"** in LM Studio's server settings. This switches the bind address to `0.0.0.0`, making the server reachable from Docker. + +You can verify connectivity from inside the container: +```bash +docker exec -it openhands-app curl -s http://host.docker.internal:1234/v1/models +``` +If this returns the model list, the connection is working. If it hangs or errors, LM Studio is still bound to localhost only. + + ### 5. Start OpenHands 1. Check [the installation guide](/openhands/usage/run-openhands/local-setup) and ensure all prerequisites are met before running OpenHands, then run: @@ -35023,6 +37046,27 @@ The PR review workflow uses the OpenHands Software Agent SDK to analyze your cod +### In a Conversation + +You can also trigger a code review manually in any OpenHands conversation. First, install the skill: + +``` +/add-skill https://github.com/OpenHands/extensions/tree/main/skills/code-review +``` + +Then invoke it: + +``` +/codereview +``` + +The agent will ask for the PR to review, or you can provide context directly: + +``` +/codereview — Please review PR #123 on my-org/my-repo. +Focus on the new authentication middleware. +``` + ## Composite Action @@ -35289,23 +37333,162 @@ See real automated reviews in action on the OpenHands Software Agent SDK reposit ## Automate This -You can schedule daily code reviews using [OpenHands Automations](/openhands/usage/automations/overview). -Copy this prompt into a new conversation to set one up: +There are two ways to automate PR reviews with OpenHands: as a **GitHub Action** (per-repo) or as an **OpenHands Automation** (org-wide, event-driven). Choose the approach that fits your needs, or use both. + +### Option A: GitHub Action (Per-Repo) + +Use the [pr-review plugin](https://github.com/OpenHands/extensions/tree/main/plugins/pr-review) as a GitHub Actions workflow. Copy the [example workflow](https://github.com/OpenHands/extensions/blob/main/plugins/pr-review/workflows/pr-review-by-openhands.yml) into `.github/workflows/pr-review.yml` in your repository, add your `LLM_API_KEY` to **Settings → Secrets and variables → Actions**, and customize the trigger conditions and model as needed. + +See the [action.yml](https://github.com/OpenHands/extensions/blob/main/plugins/pr-review/action.yml) for all available inputs (`llm-model`, `llm-base-url`, `use-sub-agents`, `require-evidence`, and more). + +**When to use this:** You want per-repo control, need to integrate with existing CI checks, or want to pin specific action versions per repository. + +### Option B: OpenHands Automation (Org-Wide) + + +Before setting up an event-driven automation, complete the one-time [prerequisites for GitHub event automations](/openhands/usage/automations/event-automations#prerequisites-for-github-event-automations) — install the GitHub App, create a team org, and claim your GitHub organization. Without these steps, GitHub events will silently never arrive. + + +[OpenHands Automations](/openhands/usage/automations/overview) is an event-triggered automation system that replaces per-repo GitHub Actions workflows. You define the trigger once and it covers all repositories matching your filter — no per-repo workflow files needed. It also leverages the full OpenHands runtime (browser, tools, sandbox), which GitHub Actions cannot. + +**When to use this:** You want a single configuration that covers all repos in your org, or you need the full OpenHands runtime for more advanced review workflows. + +#### Prerequisites: Bot Account + +For org-level automations, you should create a dedicated **bot account** (a separate GitHub user) and add it to your [OpenHands organization](/openhands/usage/cloud/organizations/overview). The bot account is the identity that will approve pull requests, request changes, and post review comments — keeping automated actions separate from human activity. Team members can then request this bot as a reviewer to trigger on-demand reviews. + +#### Setup: Create the Automation via Prompt + +Log in to [OpenHands Cloud](https://app.all-hands.dev) as your bot account (or under your team org) and send the following prompt in a new conversation. Replace the placeholders with your values: + +- `YOUR_ORG` — your GitHub organization name (e.g., `mycompany`) +- `YOUR_BOT_LOGIN` — the GitHub username of your bot account (e.g., `mycompany-bot`) +```` +Create an OpenHands Cloud automation using the Plugin Preset with the following configuration: + +**Name:** PR Review: YOUR_ORG/* (ready for review, review-this, or reviewer requested) + +**Plugin:** github:OpenHands/extensions (repo_path: plugins/pr-review) + +**Trigger events:** +- pull_request.opened +- pull_request.ready_for_review +- pull_request.review_requested +- pull_request.labeled + +**Filter:** +``` +glob(repository.full_name, 'YOUR_ORG/*') && ( + label.name == 'review-this' + || requested_reviewer.login == 'YOUR_BOT_LOGIN' + || (!label && !requested_reviewer + && pull_request.author_association != 'FIRST_TIME_CONTRIBUTOR' + && pull_request.author_association != 'FIRST_TIMER' + && pull_request.author_association != 'NONE' + && !pull_request.draft) +) ``` -Create an automation called "Daily Code Review" that runs every weekday at 9 AM. -It should: -1. Find all open PRs that have no reviews yet -2. For each PR, review the diff for bugs, style issues, and security concerns -3. Post a summary of findings as a comment on each PR +**Timeout:** 600 seconds -Learn more at https://docs.openhands.dev/openhands/usage/use-cases/code-review +**Prompt (use this exactly):** ``` +Before starting the code review, complete these steps in order: -For inline review comments on every push, use the -[pr-review plugin](https://github.com/OpenHands/extensions/tree/main/plugins/pr-review) -as a GitHub Action instead. +Step 1 — Build the session URL. +Run this in terminal: + SESSION_URL="${AUTOMATION_SESSION_URL:-${AUTOMATION_API_URL:-https://app.all-hands.dev}}" + echo "SESSION_URL=${SESSION_URL}" + +Step 2 — Extract PR info from the event payload: + PR_NUMBER=$(echo "$AUTOMATION_EVENT_PAYLOAD" | python3 -c "import sys,json; p=json.load(sys.stdin); print(p['pull_request']['number'])") + REPO=$(echo "$AUTOMATION_EVENT_PAYLOAD" | python3 -c "import sys,json; p=json.load(sys.stdin); print(p['repository']['full_name'])") + +Step 3 — Post a progress comment and save the comment ID: + COMMENT_ID=$(curl -s -X POST \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/$REPO/issues/$PR_NUMBER/comments" \ + -d "{\"body\": \"🔍 **Review in progress…**\\n\\nWe are performing the review through OpenHands Cloud Automation. You can log in and [view the conversation here](${SESSION_URL}).\"}" \ + | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])") + +Step 4 — /codereview and /github-pr-review +Review the pull request using the pr-review plugin. Post a comprehensive code review on GitHub with inline comments on specific changed lines where appropriate, and a concise overall summary. Avoid duplicating existing unresolved review comments. + +When submitting the review, choose the appropriate event type: +- Use "event": "APPROVE" when the PR is ready to merge with no blocking issues (minor suggestions are fine) +- Use "event": "REQUEST_CHANGES" when there are blocking issues that must be fixed before merging +- Use "event": "COMMENT" only when you need more information or are providing an informational review without a clear verdict + +At the end of the top-level review body include exactly: + _This review was generated by an AI agent (OpenHands) on behalf of the user through OpenHands Automation. [View conversation](${SESSION_URL})_ + +Step 5 — After the review is posted, update the progress comment: + curl -s -X PATCH \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/$REPO/issues/comments/$COMMENT_ID" \ + -d "{\"body\": \"✅ **Review complete.**\\n\\nThis review was performed through OpenHands Cloud Automation. You can log in and [view the conversation here](${SESSION_URL}).\"}" +``` +```` + + +**Team review requests:** The `requested_reviewer` field is only populated for individual reviewer requests. When a *team* is requested as reviewer, GitHub uses `requested_team` instead. To also match team requests, add `|| requested_team.slug == 'YOUR_TEAM_SLUG'` to the filter. + +**How `!label` works:** JMESPath treats absent fields as `null`, and `!null` evaluates to `true`. This means the third branch fires for `opened` and `ready_for_review` events (which have no `label` or `requested_reviewer` in the payload), while correctly staying silent for `labeled` and `review_requested` events where those fields are set. + + +#### What This Produces + +When the automation is created and a qualifying PR event occurs, the bot will: + +1. **Post a progress comment** on the PR: "🔍 Review in progress…" with a link to the live conversation +2. **Run the pr-review plugin** which analyzes the diff and posts a structured code review with inline comments — approving clean PRs, requesting changes when there are blocking issues, or leaving an informational comment when the verdict is unclear +3. **Update the progress comment** to "✅ Review complete." with the conversation link + +The automation triggers on four conditions: +- **`opened`** — when a new non-draft PR is created (for established contributors only) +- **`ready_for_review`** — when a draft PR is marked ready (for established contributors only) +- **`review_requested`** — when your bot account is requested as a reviewer. This is the primary way team members trigger an on-demand review — they simply request the bot from the PR's "Reviewers" sidebar. The bot then posts its review under its own GitHub identity, so approvals and change requests come from a clear, dedicated account. +- **`labeled`** — when the `review-this` label is added to any PR + +The automation does not re-run when new commits are pushed to an existing PR (`pull_request.synchronize` is intentionally excluded to avoid noisy re-reviews). To request a follow-up review after addressing feedback, re-add the `review-this` label or re-request the reviewer. + + +The `$AUTOMATION_SESSION_URL` variable is injected by the automation runtime and resolves to a direct link to the conversation (e.g., `https://app.all-hands.dev/conversations/{uuid}`). The prompt includes fallbacks (`$AUTOMATION_API_URL`, then the default app URL) for environments where the variable is not yet available. + +The `$AUTOMATION_EVENT_PAYLOAD` variable contains the full GitHub webhook event as JSON. The `$GITHUB_TOKEN` (from the configured GitHub integration) is also automatically available. No additional configuration is needed for any of these variables. + + +#### Single-Repo vs Org-Wide + +The prompt above uses `glob(repository.full_name, 'YOUR_ORG/*')` to cover **all repos** in your org. To target a single repo instead, replace the filter's first condition: + +``` +repository.full_name == 'YOUR_ORG/YOUR_REPO' && ( + label.name == 'review-this' + || requested_reviewer.login == 'YOUR_BOT_LOGIN' + || (!label && !requested_reviewer + && pull_request.author_association != 'FIRST_TIME_CONTRIBUTOR' + && pull_request.author_association != 'FIRST_TIMER' + && pull_request.author_association != 'NONE' + && !pull_request.draft) +) +``` + + +The `review-this` label and `requested_reviewer` branches do not exclude draft PRs — labeling a draft or requesting the bot on a draft will still fire the automation. This is intentional: explicit review requests should be honored regardless of draft status. + + +#### Testing + +After creating the automation: + +1. Add the `review-this` label to any open PR in a covered repo — this is the most reliable test since it works regardless of author history (you may need to [create the label](https://docs.github.com/en/issues/using-labels-and-milestones-to-track-work/managing-labels#creating-a-label) in your repo first if it doesn't exist) +2. Alternatively, request your bot as a reviewer on any PR, or open a new non-draft PR (note: the auto-trigger on `opened` requires the PR author to already have contributor history in that specific repo — `FIRST_TIME_CONTRIBUTOR`, `FIRST_TIMER`, and `NONE` associations are excluded) +3. Watch for the "🔍 Review in progress…" comment — it should appear within a few seconds +4. The full review will typically follow within a few minutes, depending on PR size ## Related Resources @@ -36019,37 +38202,7 @@ The QA agent knows when to give up: after exhausting multiple approaches without ### GitHub Actions -Create `.github/workflows/qa-changes.yml` in your repository: - -```yaml -name: QA Changes - -on: - pull_request: - types: [opened, ready_for_review, labeled] - -permissions: - contents: read - pull-requests: write - issues: write - -jobs: - qa: - if: | - (github.event.action == 'opened' && github.event.pull_request.draft == false) || - github.event.action == 'ready_for_review' || - github.event.label.name == 'qa-this' - runs-on: ubuntu-latest - steps: - - name: Run QA Changes - uses: OpenHands/extensions/plugins/qa-changes@main - with: - llm-model: anthropic/claude-sonnet-4-20250514 - llm-api-key: ${{ secrets.LLM_API_KEY }} - github-token: ${{ secrets.GITHUB_TOKEN }} -``` - -Add your `LLM_API_KEY` to your repository's **Settings → Secrets and variables → Actions**. +Copy the [example workflow](https://github.com/OpenHands/extensions/blob/main/plugins/qa-changes/workflows/qa-changes-by-openhands.yml) into `.github/workflows/qa-changes.yml` in your repository and add your `LLM_API_KEY` to **Settings → Secrets and variables → Actions**. See the [action.yml](https://github.com/OpenHands/extensions/blob/main/plugins/qa-changes/action.yml) for all available inputs. ### In a Conversation @@ -36160,6 +38313,55 @@ The QA agent is most powerful when used alongside the [code review agent](/openh +## Automate This + +There are two ways to automate QA testing with OpenHands: as a **GitHub Action** (per-repo) or as an **OpenHands Automation** (org-wide, event-driven). The pattern mirrors the [Automated Code Review](/openhands/usage/use-cases/code-review#automate-this) setup. + +### Option A: GitHub Action (Per-Repo) + +Use the [qa-changes plugin](https://github.com/OpenHands/extensions/tree/main/plugins/qa-changes) as a GitHub Actions workflow. Copy the [example workflow](https://github.com/OpenHands/extensions/blob/main/plugins/qa-changes/workflows/qa-changes-by-openhands.yml) into `.github/workflows/qa-changes.yml` in your repository, add your `LLM_API_KEY` to **Settings → Secrets and variables → Actions**, and customize the trigger conditions and model as needed. + +See the [action.yml](https://github.com/OpenHands/extensions/blob/main/plugins/qa-changes/action.yml) for all available inputs. + +**When to use this:** You want per-repo control, need to integrate with existing CI checks, or want to pin specific action versions per repository. + +### Option B: OpenHands Automation (Org-Wide) + + +Before setting up an event-driven automation, complete the one-time [prerequisites for GitHub event automations](/openhands/usage/automations/event-automations#prerequisites-for-github-event-automations) — install the GitHub App, create a team org, and claim your GitHub organization. Without these steps, GitHub events will silently never arrive. + + +[OpenHands Automations](/openhands/usage/automations/overview) lets you define the trigger once to cover all repositories matching your filter. Log in to [OpenHands Cloud](https://app.all-hands.dev) under your team org and send the following prompt in a new conversation. Replace `YOUR_ORG` with your GitHub organization name: + +``` +Create an OpenHands Cloud automation using the Plugin Preset with the following configuration: + +**Name:** Automated QA: YOUR_ORG/* +**Plugin:** github:OpenHands/extensions (repo_path: plugins/qa-changes) +**Trigger events:** pull_request.opened, pull_request.ready_for_review, pull_request.labeled +**Filter:** +glob(repository.full_name, 'YOUR_ORG/*') && ( + label.name == 'qa-this' + || (!label + && !pull_request.draft + && pull_request.author_association != 'FIRST_TIME_CONTRIBUTOR' + && pull_request.author_association != 'FIRST_TIMER' + && pull_request.author_association != 'NONE') +) +**Timeout:** 600 seconds + +The QA agent should: +1. Check out the PR branch +2. Exercise the changed behavior as a real user would +3. Post a structured QA report as a PR comment with evidence (commands run, outputs, screenshots) +``` + +**When to use this:** You want a single configuration that covers all repos in your org, or you need the full OpenHands runtime for more advanced QA workflows. + +When testing, you may need to [create the `qa-this` label](https://docs.github.com/en/issues/using-labels-and-milestones-to-track-work/managing-labels#creating-a-label) in your repo before you can apply it. + +For a more detailed automation setup with progress comments and session links, see the [Automated Code Review automation guide](/openhands/usage/use-cases/code-review#option-b-openhands-automation-org-wide) — the same pattern applies to QA. + ## Related Resources - [QA Changes Plugin](https://github.com/OpenHands/extensions/tree/main/plugins/qa-changes) — GitHub Actions plugin @@ -38989,31 +41191,13 @@ Source: https://docs.openhands.dev/overview/introduction.md There are a few ways to work with OpenHands: -## OpenHands Software Agent SDK -The SDK is a composable Python library that contains all of our agentic tech. It's the engine that powers everything else below. - -Define agents in code, then run them locally, or scale to 1000s of agents in the cloud - -[Check out the docs](https://docs.openhands.dev/sdk) or [view the source](https://github.com/All-Hands-AI/agent-sdk/) - -## OpenHands CLI -The CLI is the easiest way to start using OpenHands. The experience will be familiar to anyone who has worked -with e.g. Claude Code or Codex. You can power it with Claude, GPT, or any other LLM. - -[Check out the docs](https://docs.openhands.dev/openhands/usage/run-openhands/cli-mode) or [view the source](https://github.com/OpenHands/OpenHands-CLI) +## Agent Canvas +Agent Canvas is a browser-based UI and backend server for running agents and automations. A single `agent-canvas` command starts the full stack locally. Self-host on a VM, or connect to OpenHands Cloud. -## OpenHands Local GUI -Use the Local GUI for running agents on your laptop. It comes with a REST API and a single-page React application. -The experience will be familiar to anyone who has used Devin or Jules. - -[Check out the docs](https://docs.openhands.dev/openhands/usage/run-openhands/local-setup) or view the source in this repo. +[Get started with Agent Canvas](/openhands/usage/agent-canvas/overview) or [view the source](https://github.com/OpenHands/agent-canvas) ## OpenHands Cloud -This is a commercial deployment of OpenHands GUI, running on hosted infrastructure. - -You can try it with a free by [signing in with your GitHub account](https://app.all-hands.dev). - -OpenHands Cloud comes with source-available features and integrations: +A fully managed version of OpenHands with source-available features and integrations: - Deeper integrations with GitHub, GitLab, and Bitbucket - Integrations with Slack, Jira, and Linear - Multi-user support @@ -39022,6 +41206,8 @@ OpenHands Cloud comes with source-available features and integrations: - Usage reporting - Budgeting enforcement +Try it free by [signing in with your GitHub account](https://app.all-hands.dev). + ## OpenHands Enterprise Large enterprises can work with us to self-host OpenHands Cloud in their own VPC, via Kubernetes. OpenHands Enterprise can also work with the CLI and SDK above. @@ -39033,6 +41219,29 @@ Enterprise contracts also come with extended support and access to our research Learn more at [openhands.dev/enterprise](https://openhands.dev/enterprise) +## OpenHands Software Agent SDK +The SDK is a composable Python library that contains all of our agentic tech. It's the engine that powers everything else. + +Define agents in code, then run them locally, or scale to 1000s of agents in the cloud. + +[Check out the docs](https://docs.openhands.dev/sdk) or [view the source](https://github.com/All-Hands-AI/agent-sdk/) + +## Legacy + + + **OpenHands CLI** + + The CLI is a terminal-based interface for running OpenHands agents. You can power it with Claude, GPT, or any other LLM. + + [Check out the docs](https://docs.openhands.dev/openhands/usage/run-openhands/cli-mode) or [view the source](https://github.com/OpenHands/OpenHands-CLI) + + **OpenHands Local GUI** + + A legacy UI requiring Docker for running agents on your laptop. It comes with a REST API and a single-page React application. + + [Check out the docs](https://docs.openhands.dev/openhands/usage/run-openhands/local-setup) or view the source in this repo. + + ## Everything Else Check out our [Product Roadmap](https://github.com/orgs/openhands/projects/1), and feel free to @@ -39687,31 +41896,14 @@ For SDK developers: ### Quick Start Source: https://docs.openhands.dev/overview/quickstart.md -Get started with OpenHands in minutes. Choose the option that works best for you. - - - - **Recommended** - - The fastest way to get started. No setup required—just sign in and start coding. - - - Free usage of MiniMax M2.5 for a limited time - - No installation needed - - Managed infrastructure - - - Use OpenHands from your terminal. Perfect for automation and scripting. +Get started with OpenHands in minutes. - - IDE integrations available - - Headless mode for CI/CD - - Lightweight installation + + + The recommended way to run OpenHands. Install via npm or Docker and start your first conversation in minutes. - - Run OpenHands locally with a web-based interface. Bring your own LLM and API key. - - - Full control over your environment - - Works offline - - Docker-based setup + + No installation required — sign in and start coding. @@ -42578,6 +44770,214 @@ For production deployments, we recommend integrating with a monitoring solution +### Plugin Marketplace +Source: https://docs.openhands.dev/enterprise/plugin-marketplace.md + +
+
+The Plugin Marketplace is an opt-in feature that adds a browseable catalog of community-built +OpenHands plugins to your Enterprise deployment. Once enabled, users can discover and review +plugins directly at `/plugins` on your application hostname. + + + The Plugin Marketplace is an experimental feature. Enable it only after your + OpenHands Enterprise deployment is fully operational. + +
+
+ Plugin Marketplace demo +
+
+ +## Prerequisites + +- A running OpenHands Enterprise deployment. See [Quick Start](/enterprise/quick-start) if + you haven't already deployed. +- The bundled or [external PostgreSQL](/enterprise/external-postgres) database must be reachable. + The marketplace creates a separate `plugindir` database to store plugin metadata. +- A Marketplace Source URI pointing to a plugin catalog (see [Marketplace Source URI](#marketplace-source-uri)). + +## Enable the Plugin Marketplace + + + + The Plugin Marketplace is configured through the Replicated Admin Console. + + ### 1. Open the Admin Console + + Navigate to `https://:30000` and log in. + + ### 2. Open the configuration page + + Click **Config** in the top navigation bar to open the application configuration page. + + ### 3. Enable the Plugin Directory + + Scroll to the **Experimental** section near the bottom of the configuration page. + + Check the **Enable Plugin Directory** box. + + ![Enable Plugin Directory](/enterprise/images/Experimental-PluginMarketplace.png) + + ### 4. Set the Marketplace Source + + Once **Enable Plugin Directory** is checked, a **Marketplace Source** field appears. + + Enter the URI of the plugin catalog you want to load. For example: + + ```text + github://AcmeCo/plugin-directory + ``` + + To pin to a specific release of the catalog, append a `@ref` tag: + + ```text + github://AcmeCo/plugin-directory@v1.0.0 + ``` + + See [Marketplace Source URI](#marketplace-source-uri) for a full description of supported formats. + + ### 5. Save and deploy + + Scroll to the bottom of the configuration page and click **Save config**, then click **Deploy** + to apply the changes. + + The deployment status will show **Unavailable** while the Plugin Directory pods start, then + transition to **Ready** once all components are healthy. + + + + If you deployed OpenHands Enterprise into your own Kubernetes cluster using Helm, enable the + Plugin Marketplace by adding the following values to your `values.yaml` override file. + + ### Required values + + ```yaml + plugin-directory: + enabled: true + + # Full URL where the plugin catalog is served + appUrl: "https://app./plugins" + + # Base URL used in in-page curl examples + curlApiUrl: "https://app." + + appEnv: + # URI of the plugin catalog to load (required) + MARKETPLACE_SOURCE: "github://AcmeCo/plugin-directory" + + database: + host: "" + name: "plugindir" + # Name of the Kubernetes Secret that contains the PostgreSQL password + secretName: "postgres-password" + secretKey: "password" + + auth: + # Secret created by the openhands-secrets chart + existingSecret: plugin-directory-secrets + + oidc: + # Keycloak issuer URL — must match your Keycloak realm + issuerUrl: "https://auth.app." + realmSecretName: "keycloak-realm" + ``` + + ### Required secrets + + The Plugin Directory needs two shared secrets for inter-service authentication and session + management. Add these to your `openhands-secrets` chart values: + + ```yaml + plugin_directory_identity_shared_secret: "" + plugin_directory_session_secret: "" + ``` + + Generate each value with: + + ```bash + openssl rand -hex 16 + ``` + + ### Apply the changes + + ```bash + helm upgrade openhands oci://ghcr.io/openhands/helm-charts/openhands \ + --namespace openhands \ + --values values.yaml + ``` + + ### Database migration + + On first deployment, init containers automatically create the `plugindir` database and run + Alembic migrations. No manual database setup is required. + + + If you use an external PostgreSQL instance with `databaseMigrations.createDatabases: false`, + create the `plugindir` database manually before deploying. + + + + +## Marketplace Source URI + +The `MARKETPLACE_SOURCE` value (or **Marketplace Source** field in the Admin Console) tells the +Plugin Directory server where to load its plugin catalog from. + +| Format | Example | Notes | +|--------|---------|-------| +| `github://owner/repo` | `github://AcmeCo/plugin-directory` | Loads from the default branch of the repository | +| `github://owner/repo@ref` | `github://AcmeCo/plugin-directory@v1.2.0` | Loads from a specific branch, tag, or commit SHA | +| `https://example.com/catalog.json` | `https://cdn.example.com/plugins/catalog.json` | Loads a catalog JSON file over HTTPS | + + +To host a private or curated catalog, point the URI to a GitHub repository or an HTTPS URL that +serves a compatible catalog JSON file. + +## Accessing the Marketplace + +Once the deployment is complete and shows **Ready**, the Plugin Marketplace is available at: + +```text +https://app./plugins +``` + +Users authenticate through the same Keycloak SSO used for the rest of OpenHands Enterprise. +The Plugin Directory API is also available at: + +```text +https://app./api/plugins +``` + +## Disabling the Plugin Marketplace + + + + Open the Admin Console, navigate to **Config**, uncheck **Enable Plugin Directory** in the + **Experimental** section, click **Save config**, then **Deploy**. + + + Set `plugin-directory.enabled: false` in your `values.yaml` and run `helm upgrade`. + + + +## Next Steps + + + + Install or review the full OpenHands Enterprise deployment guide. + + + Configure an external PostgreSQL database for OpenHands Enterprise. + + + Deploy OpenHands Enterprise into your own Kubernetes cluster using Helm. + + + Learn about all OpenHands Enterprise features and deployment options. + + + ### Quick Start Source: https://docs.openhands.dev/enterprise/quick-start.md diff --git a/llms.txt b/llms.txt index df66d520..db4e21fa 100644 --- a/llms.txt +++ b/llms.txt @@ -53,6 +53,7 @@ from the OpenHands Software Agent SDK. - [Model Context Protocol](https://docs.openhands.dev/sdk/guides/mcp.md): Model Context Protocol (MCP) enables dynamic tool integration from external servers. Agents can discover and use MCP-provided tools automatically. - [Model Routing](https://docs.openhands.dev/sdk/guides/llm-routing.md): Route agent's LLM requests to different models. - [Observability & Tracing](https://docs.openhands.dev/sdk/guides/observability.md): Enable OpenTelemetry tracing to monitor and debug your agent's execution with tools like Laminar, MLflow, Honeycomb, or any OTLP-compatible backend. +- [OpenAI-Compatible Endpoint](https://docs.openhands.dev/sdk/guides/agent-server/openai-gateway.md): Call an OpenHands agent-server through the OpenAI Chat Completions protocol. - [OpenHands Cloud Workspace](https://docs.openhands.dev/sdk/guides/agent-server/cloud-workspace.md): Connect to OpenHands Cloud for fully managed sandbox environments with optional SaaS credential inheritance. - [openhands.sdk.agent](https://docs.openhands.dev/sdk/api-reference/openhands.sdk.agent.md): API reference for openhands.sdk.agent module - [openhands.sdk.conversation](https://docs.openhands.dev/sdk/api-reference/openhands.sdk.conversation.md): API reference for openhands.sdk.conversation module @@ -107,6 +108,8 @@ from the OpenHands Software Agent SDK. ## OpenHands Web App Server - [About OpenHands](https://docs.openhands.dev/openhands/usage/about.md) +- [ACP Agents](https://docs.openhands.dev/openhands/usage/agent-canvas/acp-agents.md): Drive Agent Canvas conversations with an external coding agent — Claude Code, Codex, or Gemini CLI — over the Agent Client Protocol. +- [Agent Canvas Overview](https://docs.openhands.dev/openhands/usage/agent-canvas/overview.md): A lightweight platform to run agents and automations — locally or in the cloud. - [API Keys Settings](https://docs.openhands.dev/openhands/usage/settings/api-keys-settings.md): View your OpenHands LLM key and create API keys to work with OpenHands programmatically. - [Application Settings](https://docs.openhands.dev/openhands/usage/settings/application-settings.md): Configure application-level settings for OpenHands. - [Automated Code Review](https://docs.openhands.dev/openhands/usage/use-cases/code-review.md): Set up automated PR reviews using OpenHands and the Software Agent SDK @@ -115,28 +118,40 @@ from the OpenHands Software Agent SDK. - [AWS Bedrock](https://docs.openhands.dev/openhands/usage/llms/aws-bedrock.md): OpenHands uses LiteLLM to make calls to AWS Bedrock models. You can find their documentation on using Bedrock as a provider [here](https://docs.litellm.ai/docs/providers/bedrock). - [Azure](https://docs.openhands.dev/openhands/usage/llms/azure-llms.md): OpenHands uses LiteLLM to make calls to Azure's chat models. You can find their documentation on using Azure as a provider [here](https://docs.litellm.ai/docs/providers/azure). - [Backend Architecture](https://docs.openhands.dev/openhands/usage/architecture/backend.md) +- [Backends](https://docs.openhands.dev/openhands/usage/agent-canvas/backends.md): Understand and manage Agent Canvas backends. +- [Cloud Backend](https://docs.openhands.dev/openhands/usage/agent-canvas/backend-setup/cloud.md): Connect Agent Canvas to OpenHands Cloud for on-demand sandboxed execution. - [COBOL Modernization](https://docs.openhands.dev/openhands/usage/use-cases/cobol-modernization.md): Modernizing legacy COBOL systems with OpenHands - [Configuration Options](https://docs.openhands.dev/openhands/usage/advanced/configuration-options.md): How to configure OpenHands V1 (Web UI, env vars, and sandbox settings). - [Configure](https://docs.openhands.dev/openhands/usage/run-openhands/gui-mode.md): High level overview of configuring the OpenHands Web interface. +- [Contributing](https://docs.openhands.dev/openhands/usage/agent-canvas/development.md): Contribute to Agent Canvas development. - [Creating Automations](https://docs.openhands.dev/openhands/usage/automations/creating-automations.md): Learn how to create scheduled automations using the Automation Skill. +- [Critic](https://docs.openhands.dev/openhands/usage/agent-canvas/critic.md): Configure critic evaluation and iterative refinement in Agent Canvas. - [Custom LLM Configurations](https://docs.openhands.dev/openhands/usage/llms/custom-llm-configs.md): OpenHands supports defining multiple named LLM configurations in your `config.toml` file. This feature allows you to use different LLM configurations for different purposes, such as using a cheaper model for tasks that don't require high-quality responses, or using different models with different parameters for specific agents. - [Custom Sandbox](https://docs.openhands.dev/openhands/usage/advanced/custom-sandbox-guide.md): This guide is for users that would like to use their own custom Docker image for the runtime. +- [Customize and Settings](https://docs.openhands.dev/openhands/usage/agent-canvas/customize-and-settings.md): Teach your agent with skills and MCP servers, and configure how it runs with settings. - [Debugging](https://docs.openhands.dev/openhands/usage/developers/debugging.md) - [Dependency Upgrades](https://docs.openhands.dev/openhands/usage/use-cases/dependency-upgrades.md): Automating dependency updates and upgrades with OpenHands - [Development Overview](https://docs.openhands.dev/openhands/usage/developers/development-overview.md): This guide provides an overview of the key documentation resources available in the OpenHands repository. Whether you're looking to contribute, understand the architecture, or work on specific components, these resources will help you navigate the codebase effectively. +- [Docker Backend](https://docs.openhands.dev/openhands/usage/agent-canvas/backend-setup/docker.md): Run Agent Canvas in a Docker container as a sandboxed backend. - [Docker Sandbox](https://docs.openhands.dev/openhands/usage/sandboxes/docker.md): The recommended sandbox provider for running OpenHands locally. - [Environment Variables Reference](https://docs.openhands.dev/openhands/usage/environment-variables.md): Complete reference of all environment variables supported by OpenHands - [Evaluation Harness](https://docs.openhands.dev/openhands/usage/developers/evaluation-harness.md) - [Event-Based Automations](https://docs.openhands.dev/openhands/usage/automations/event-automations.md): Trigger automations from GitHub events or custom webhooks instead of cron schedules. +- [First Time Setup](https://docs.openhands.dev/openhands/usage/agent-canvas/first-time-setup.md): Configure Agent Canvas after installation — choose your agent, connect a backend, add an LLM, and launch your first automation. +- [GitHub PR Review Assistant](https://docs.openhands.dev/openhands/usage/agent-canvas/prebuilt/github-pr-review.md): Automatically review pull requests using an OpenHands agent. +- [GitHub Repository Monitor](https://docs.openhands.dev/openhands/usage/agent-canvas/prebuilt/github-repo-monitor.md): Monitor a GitHub repository and trigger agent actions on events. - [Good vs. Bad Instructions](https://docs.openhands.dev/openhands/usage/essential-guidelines/good-vs-bad-instructions.md): Learn how to write effective instructions for OpenHands - [Google Gemini/Vertex](https://docs.openhands.dev/openhands/usage/llms/google-llms.md): OpenHands uses LiteLLM to make calls to Google's chat models. You can find their documentation on using Google as a provider -> [Gemini - Google AI Studio](https://docs.litellm.ai/docs/providers/gemini), [VertexAI - Google Cloud Platform](https://docs.litellm.ai/docs/providers/vertex) - [Groq](https://docs.openhands.dev/openhands/usage/llms/groq.md): OpenHands uses LiteLLM to make calls to chat models on Groq. You can find their documentation on using Groq as a provider [here](https://docs.litellm.ai/docs/providers/groq). - [Hooks](https://docs.openhands.dev/openhands/usage/customization/hooks.md): Use lifecycle hooks to control agent behavior - block dangerous commands, enforce quality checks before stopping, inject context, and more. - [Incident Triage](https://docs.openhands.dev/openhands/usage/use-cases/incident-triage.md): Using OpenHands to investigate and resolve production incidents +- [Install](https://docs.openhands.dev/openhands/usage/agent-canvas/setup.md): Install and run Agent Canvas via npm or Docker. - [Integrations Settings](https://docs.openhands.dev/openhands/usage/settings/integrations-settings.md): How to setup and modify the various integrations in OpenHands. - [Key Features](https://docs.openhands.dev/openhands/usage/key-features.md) - [Language Model (LLM) Settings](https://docs.openhands.dev/openhands/usage/settings/llm-settings.md): This page goes over how to set the LLM to use in OpenHands, including LLM profiles for switching models during conversations. - [LiteLLM Proxy](https://docs.openhands.dev/openhands/usage/llms/litellm-proxy.md): OpenHands supports using the [LiteLLM proxy](https://docs.litellm.ai/docs/proxy/quick_start) to access various LLM providers. +- [LLM Profiles and Model Configuration](https://docs.openhands.dev/openhands/usage/agent-canvas/llm-profiles.md): Configure models in Agent Canvas and use saved LLM profiles during conversations. +- [Local Backend](https://docs.openhands.dev/openhands/usage/agent-canvas/backend-setup/local.md): Run one or more local backends and connect to them from the Agent Canvas UI. - [Local LLMs](https://docs.openhands.dev/openhands/usage/llms/local-llms.md): When using a Local LLM, OpenHands may have limited functionality. It is highly recommended that you use GPUs to serve local models for optimal experience. - [Main Agent and Capabilities](https://docs.openhands.dev/openhands/usage/agents.md) - [Managing Automations](https://docs.openhands.dev/openhands/usage/automations/managing-automations.md): List, update, enable, disable, and delete your automations. @@ -158,10 +173,14 @@ from the OpenHands Software Agent SDK. - [Search Engine Setup](https://docs.openhands.dev/openhands/usage/advanced/search-engine-setup.md): Configure OpenHands to use Tavily as a search engine. - [Secrets Management](https://docs.openhands.dev/openhands/usage/settings/secrets-settings.md): How to manage secrets in OpenHands. - [Setup](https://docs.openhands.dev/openhands/usage/run-openhands/local-setup.md): Getting started with running OpenHands on your own. +- [Setup a Pre-built Automation](https://docs.openhands.dev/openhands/usage/agent-canvas/prebuilt-automations.md): Get started quickly with a pre-built automation for common workflows. +- [Slack Channel Monitor](https://docs.openhands.dev/openhands/usage/agent-canvas/prebuilt/slack-channel-monitor.md): Watch a Slack channel and trigger agent actions on messages. - [Spark Migrations](https://docs.openhands.dev/openhands/usage/use-cases/spark-migrations.md): Migrating Apache Spark applications with OpenHands +- [Troubleshooting](https://docs.openhands.dev/openhands/usage/agent-canvas/troubleshooting.md): Common Agent Canvas setup and runtime issues, plus places to ask for help. - [Troubleshooting](https://docs.openhands.dev/openhands/usage/troubleshooting/troubleshooting.md) - [Tutorial Library](https://docs.openhands.dev/openhands/usage/get-started/tutorials.md): Centralized hub for OpenHands tutorials and examples - [Use Cases Overview](https://docs.openhands.dev/openhands/usage/use-cases/overview.md): Explore how OpenHands can help with common software development challenges +- [VM / Self-Hosted Installation](https://docs.openhands.dev/openhands/usage/agent-canvas/backend-setup/vm.md): Install Agent Canvas on a VM as a backend-only service or full self-hosted Canvas. - [Vulnerability Remediation](https://docs.openhands.dev/openhands/usage/use-cases/vulnerability-remediation.md): Using OpenHands to identify and fix security vulnerabilities in your codebase - [WebSocket Connection](https://docs.openhands.dev/openhands/usage/developers/websocket-connection.md) - [When to Use OpenHands](https://docs.openhands.dev/openhands/usage/essential-guidelines/when-to-use-openhands.md): Guidance on when OpenHands is the right tool for your task @@ -213,6 +232,7 @@ from the OpenHands Software Agent SDK. - [Jira Data Center](https://docs.openhands.dev/enterprise/integrations/jira-data-center.md): Configure Jira Data Center for OpenHands Enterprise. - [Kubernetes Installation](https://docs.openhands.dev/enterprise/k8s-install.md): Deploy OpenHands Enterprise into your own Kubernetes cluster using Helm - [OpenHands Enterprise](https://docs.openhands.dev/enterprise.md): Run AI coding agents on your own infrastructure with complete control +- [Plugin Marketplace](https://docs.openhands.dev/enterprise/plugin-marketplace.md): Enable and configure the Plugin Marketplace to browse and install community-built OpenHands plugins. - [Quick Start](https://docs.openhands.dev/enterprise/quick-start.md): Get started with a 30-day trial of OpenHands Enterprise. - [Resource Limits](https://docs.openhands.dev/enterprise/k8s-install/resource-limits.md): Configure memory, CPU, and storage for OpenHands Enterprise components - [Slack](https://docs.openhands.dev/enterprise/integrations/slack.md): Configure the Slack integration for a self-hosted OpenHands Enterprise install.