From 89b876314eceb65249beb5ac0c3a6634a960e210 Mon Sep 17 00:00:00 2001 From: openhands Date: Wed, 20 May 2026 15:39:01 +0000 Subject: [PATCH 1/6] Add Agent Canvas documentation Co-authored-by: openhands --- AGENTS.md | 3 + docs.json | 16 +- enterprise/enterprise-vs-oss.mdx | 4 +- llms-full.txt | 2414 +++++++++++++---- llms.txt | 19 +- .../usage/advanced/custom-sandbox-guide.mdx | 2 +- openhands/usage/agent-canvas/automations.mdx | 42 + openhands/usage/agent-canvas/backends.mdx | 63 + .../agent-canvas/customize-and-settings.mdx | 56 + openhands/usage/agent-canvas/development.mdx | 81 + openhands/usage/agent-canvas/llm-profiles.mdx | 49 + openhands/usage/agent-canvas/overview.mdx | 45 + openhands/usage/agent-canvas/self-hosting.mdx | 75 + openhands/usage/agent-canvas/setup.mdx | 85 + .../usage/agent-canvas/troubleshooting.mdx | 65 + openhands/usage/cli/gui-server.mdx | 2 +- openhands/usage/run-openhands/gui-mode.mdx | 5 + openhands/usage/run-openhands/local-setup.mdx | 5 + .../usage/settings/integrations-settings.mdx | 2 +- .../v0/advanced/V0_configuration-options.mdx | 2 +- openhands/usage/v0/runtimes/V0_overview.mdx | 2 +- overview/introduction.mdx | 7 +- overview/model-context-protocol.mdx | 10 +- overview/quickstart.mdx | 10 +- overview/skills.mdx | 10 +- 25 files changed, 2469 insertions(+), 605 deletions(-) create mode 100644 openhands/usage/agent-canvas/automations.mdx create mode 100644 openhands/usage/agent-canvas/backends.mdx create mode 100644 openhands/usage/agent-canvas/customize-and-settings.mdx create mode 100644 openhands/usage/agent-canvas/development.mdx create mode 100644 openhands/usage/agent-canvas/llm-profiles.mdx create mode 100644 openhands/usage/agent-canvas/overview.mdx create mode 100644 openhands/usage/agent-canvas/self-hosting.mdx create mode 100644 openhands/usage/agent-canvas/setup.mdx create mode 100644 openhands/usage/agent-canvas/troubleshooting.mdx diff --git a/AGENTS.md b/AGENTS.md index de1edc63b..018039270 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -15,6 +15,9 @@ The site is built with **Mintlify** and deployed automatically by Mintlify on pu - `docs.json` — Mintlify site configuration (nav tabs, redirects, OpenAPI integration) - `overview/` — high-level docs (intro, quickstart, community, skills overview) - `openhands/usage/` — product docs for Web/Cloud/CLI/etc. +- `openhands/usage/agent-canvas/` — Agent Canvas Beta docs (setup, backends, development, profiles, customize/settings, automations, self-hosting, troubleshooting) +- `openhands/usage/run-openhands/local-setup.mdx` and related Local GUI pages remain on their existing URLs as **Local GUI (Legacy)** docs; prefer Agent Canvas pages for the current local/self-hosted UI + - `sdk/` — Agent SDK docs (guides, architecture, API reference pages) - `openapi/` — OpenAPI specs consumed by Mintlify - `openapi/openapi.json` — OpenHands REST API schema diff --git a/docs.json b/docs.json index 52134ec4e..d58ff56e4 100644 --- a/docs.json +++ b/docs.json @@ -114,7 +114,21 @@ ] }, { - "group": "Local GUI", + "group": "Agent Canvas (Beta)", + "pages": [ + "openhands/usage/agent-canvas/overview", + "openhands/usage/agent-canvas/setup", + "openhands/usage/agent-canvas/backends", + "openhands/usage/agent-canvas/development", + "openhands/usage/agent-canvas/llm-profiles", + "openhands/usage/agent-canvas/customize-and-settings", + "openhands/usage/agent-canvas/automations", + "openhands/usage/agent-canvas/self-hosting", + "openhands/usage/agent-canvas/troubleshooting" + ] + }, + { + "group": "Local GUI (Legacy)", "pages": [ "openhands/usage/run-openhands/local-setup", "openhands/usage/run-openhands/gui-mode", diff --git a/enterprise/enterprise-vs-oss.mdx b/enterprise/enterprise-vs-oss.mdx index 369c10d7f..3bb0f7a6a 100644 --- a/enterprise/enterprise-vs-oss.mdx +++ b/enterprise/enterprise-vs-oss.mdx @@ -52,9 +52,9 @@ OpenHands Enterprise is the right choice when you need: - Get started with OpenHands on your local machine using Docker or the CLI launcher. + Install Agent Canvas from npm and run OpenHands from your terminal. ` ``` ** @@ -3257,7 +3257,7 @@ Complex tool with initialization parameters: : class TerminalTool(ToolDefinition[TerminalAction, : TerminalObservation]): @classmethod - def create(cls, conv_state, + def create(cls, conv_state, `
` ``` ** @@ -3918,18 +3918,18 @@ flowchart TB Events["Event History"] Context["Agent Context
Skills + Prompts"] end - + subgraph Core["Agent Core"] Condense["Condenser
History compression"] Reason["LLM Query
Generate actions"] Security["Security Analyzer
Risk assessment"] end - + subgraph Execution[" "] Tools["Tool Executor
Action → Observation"] Results["Observation Events"] end - + Events --> Condense Context -.->|Skills| Reason Condense --> Reason @@ -3937,11 +3937,11 @@ flowchart TB Security --> Tools Tools --> Results Results -.->|Feedback| Events - + classDef primary fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px classDef secondary fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px classDef tertiary fill:#fff4df,stroke:#b7791f,stroke-width:2px - + class Reason primary class Condense,Security secondary class Tools tertiary @@ -3967,55 +3967,55 @@ flowchart TB Start["step() called"] Pending{"Pending
actions?"} ExecutePending["Execute pending actions"] - + HasCondenser{"Has
condenser?"} Condense["Call condenser.condense()"] CondenseResult{"Result
type?"} EmitCondensation["Emit Condensation event"] UseView["Use View events"] UseRaw["Use raw events"] - + Query["Query LLM with messages"] ContextExceeded{"Context
window
exceeded?"} EmitRequest["Emit CondensationRequest"] - + Parse{"Response
type?"} CreateActions["Create ActionEvents"] CreateMessage["Create MessageEvent"] - + Confirmation{"Need
confirmation?"} SetWaiting["Set WAITING_FOR_CONFIRMATION"] - + Execute["Execute actions"] Observe["Create ObservationEvents"] - + Return["Return"] - + Start --> Pending Pending -->|Yes| ExecutePending --> Return Pending -->|No| HasCondenser - + HasCondenser -->|Yes| Condense HasCondenser -->|No| UseRaw Condense --> CondenseResult CondenseResult -->|Condensation| EmitCondensation --> Return CondenseResult -->|View| UseView --> Query UseRaw --> Query - + Query --> ContextExceeded ContextExceeded -->|Yes| EmitRequest --> Return ContextExceeded -->|No| Parse - + Parse -->|Tool calls| CreateActions Parse -->|Message| CreateMessage --> Return - + CreateActions --> Confirmation Confirmation -->|Yes| SetWaiting --> Return Confirmation -->|No| Execute - + Execute --> Observe Observe --> Return - + style Query fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Condense fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Confirmation fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -4050,26 +4050,26 @@ The agent applies `AgentContext` which includes **skills** and **prompts** to sh %%{init: {"theme": "default", "flowchart": {"nodeSpacing": 30}} }%% flowchart LR Context["AgentContext"] - + subgraph Skills["Skills"] Repo["repo
Always active"] Knowledge["knowledge
Trigger-based"] end SystemAug["System prompt prefix/suffix
Per-conversation"] System["Prompt template
Per-conversation"] - + subgraph Application["Applied to LLM"] SysPrompt["System Prompt"] UserMsg["User Messages"] end - + Context --> Skills Context --> SystemAug Repo --> SysPrompt Knowledge -.->|When triggered| UserMsg System --> SysPrompt SystemAug --> SysPrompt - + style Context fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Repo fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Knowledge fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -4092,26 +4092,26 @@ Tools follow a **strict action-observation pattern**: flowchart TB LLM["LLM generates tool_call"] Convert["Convert to ActionEvent"] - + Decision{"Confirmation
mode?"} Defer["Store as pending"] - + Execute["Execute tool"] Success{"Success?"} - + Obs["ObservationEvent
with result"] Error["ObservationEvent
with error"] - + LLM --> Convert Convert --> Decision - + Decision -->|Yes| Defer Decision -->|No| Execute - + Execute --> Success Success -->|Yes| Obs Success -->|No| Error - + style Convert fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Execute fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Decision fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -4143,14 +4143,14 @@ flowchart LR LLM["LLM"] Tools["Tools"] Context["AgentContext"] - + Conv -->|.step calls| Agent Agent -->|Reads events| Conv Agent -->|Query| LLM Agent -->|Execute| Tools Context -.->|Skills and Context| Agent Agent -.->|New events| Conv - + style Agent fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Conv fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style LLM fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -4192,23 +4192,23 @@ The Agent Server enables: ```mermaid graph TB Client[Web/Mobile Client] -->|HTTPS| API[FastAPI Server] - + API --> Auth[Authentication] API --> Router[API Router] - + Router --> WS[Workspace Manager] Router --> Conv[Conversation Handler] - + WS --> Docker[Docker Manager] Docker --> C1[Container 1
User A] Docker --> C2[Container 2
User B] Docker --> C3[Container 3
User C] - + Conv --> Agent[Software Agent SDK] Agent --> C1 Agent --> C2 Agent --> C3 - + style Client fill:#e1f5fe style API fill:#fff3e0 style WS fill:#e8f5e8 @@ -4329,7 +4329,7 @@ curl -H "Authorization: Bearer YOUR_API_KEY" \ async with websocket_connect(url) as ws: # Send message await ws.send_json({"message": "Hello"}) - + # Receive events async for event in ws: if event["type"] == "message": @@ -4539,39 +4539,47 @@ curl https://agent-server.example.com/health - Resource exhaustion - Container failures -## Client SDK +## Client Integration Architecture -Python SDK for interacting with Agent Server: +The SDK implements a **workspace-based dispatch pattern** for connecting to agent servers. The `Conversation` factory inspects the workspace type and returns the appropriate conversation implementation. -```python -from openhands.client import AgentServerClient +```mermaid +flowchart LR + Conv["Conversation()"] --> Check{"Workspace Type?"} + Check -->|LocalWorkspace| Local["LocalConversation"] + Check -->|RemoteWorkspace| Remote["RemoteConversation"] + Remote -->|HTTP/WebSocket| Server["Agent Server"] -client = AgentServerClient( - url="https://agent-server.example.com", - api_key="your-api-key" -) + style Conv fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px + style Remote fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px + style Server fill:#fff4df,stroke:#b7791f,stroke-width:2px +``` -# Create conversation -conversation = client.create_conversation() +### Workspace Types -# Send message -response = client.send_message( - conversation_id=conversation.id, - message="Hello, agent!" -) +| Workspace | Conversation Type | Communication | +|-----------|------------------|---------------| +| [`LocalWorkspace`](https://github.com/OpenHands/software-agent-sdk/blob/main/openhands-sdk/openhands/sdk/workspace/local.py) | [`LocalConversation`](https://github.com/OpenHands/software-agent-sdk/blob/main/openhands-sdk/openhands/sdk/conversation/impl/local_conversation.py) | Direct execution | +| [`OpenHandsCloudWorkspace`](https://github.com/OpenHands/software-agent-sdk/blob/main/openhands-workspace/openhands/workspace/cloud/workspace.py) | [`RemoteConversation`](https://github.com/OpenHands/software-agent-sdk/blob/main/openhands-sdk/openhands/sdk/conversation/impl/remote_conversation.py) | HTTPS + WebSocket to OpenHands Cloud | +| [`APIRemoteWorkspace`](https://github.com/OpenHands/software-agent-sdk/blob/main/openhands-workspace/openhands/workspace/remote_api/workspace.py) | [`RemoteConversation`](https://github.com/OpenHands/software-agent-sdk/blob/main/openhands-sdk/openhands/sdk/conversation/impl/remote_conversation.py) | HTTPS + WebSocket to Runtime API | +| [`DockerWorkspace`](https://github.com/OpenHands/software-agent-sdk/blob/main/openhands-workspace/openhands/workspace/docker/workspace.py) | [`RemoteConversation`](https://github.com/OpenHands/software-agent-sdk/blob/main/openhands-sdk/openhands/sdk/conversation/impl/remote_conversation.py) | HTTP + WebSocket to local container | -# Stream responses -for event in client.stream_conversation(conversation.id): - if event.type == "message": - print(event.content) -``` +### [`RemoteConversation`](https://github.com/OpenHands/software-agent-sdk/blob/main/openhands-sdk/openhands/sdk/conversation/impl/remote_conversation.py) Responsibilities + +The `RemoteConversation` implementation handles all client-server concerns: + +- **Session management**: Authenticates and maintains connection to agent server +- **Event streaming**: WebSocket connection for real-time agent events +- **Request routing**: HTTP calls for conversation lifecycle operations +- **Reconnection**: Automatic retry logic for transient failures -**Client handles**: -- Authentication -- Request/response serialization -- Error handling -- Streaming -- Retries +### Usage Examples + +For complete working examples with all required setup: + +- **[OpenHands Cloud Workspace](/sdk/guides/agent-server/cloud-workspace)** - Managed cloud infrastructure +- **[API-based Sandbox](/sdk/guides/agent-server/api-sandbox)** - Custom runtime environments +- **[Docker Sandbox](/sdk/guides/agent-server/docker-sandbox)** - Local containerized execution ## Cost Considerations @@ -4617,11 +4625,11 @@ WORKSPACE_CONFIG = { ### Use Agent Server When: -✅ **Multi-user system**: Web app with many users -✅ **Remote clients**: Mobile app, web frontend -✅ **Centralized management**: Need to monitor all agents -✅ **Workspace isolation**: Users shouldn't interfere -✅ **SaaS product**: Building agent-as-a-service +✅ **Multi-user system**: Web app with many users +✅ **Remote clients**: Mobile app, web frontend +✅ **Centralized management**: Need to monitor all agents +✅ **Workspace isolation**: Users shouldn't interfere +✅ **SaaS product**: Building agent-as-a-service ✅ **Scaling**: Need to handle concurrent users **Examples**: @@ -4632,10 +4640,10 @@ WORKSPACE_CONFIG = { ### Use Standalone SDK When: -✅ **Single-user**: Personal tool or script -✅ **Local execution**: Running on your machine -✅ **Full control**: Need programmatic access -✅ **Simpler deployment**: No server management +✅ **Single-user**: Personal tool or script +✅ **Local execution**: Running on your machine +✅ **Full control**: Need programmatic access +✅ **Simpler deployment**: No server management ✅ **Lower latency**: No network overhead **Examples**: @@ -4728,40 +4736,40 @@ flowchart TB subgraph Interface["Abstract Interface"] Base["CondenserBase
Abstract base"] end - + subgraph Implementations["Concrete Implementations"] NoOp["NoOpCondenser
No compression"] LLM["LLMSummarizingCondenser
LLM-based"] Pipeline["PipelineCondenser
Multi-stage"] end - + subgraph Process["Condensation Process"] View["View
Event history"] Check["should_condense()?"] Condense["get_condensation()"] Result["View | Condensation"] end - + subgraph Output["Condensation Output"] CondEvent["Condensation Event
Summary metadata"] NewView["Condensed View
Reduced tokens"] end - + Base --> NoOp Base --> LLM Base --> Pipeline - + View --> Check Check -->|Yes| Condense Check -->|No| Result Condense --> CondEvent CondEvent --> NewView NewView --> Result - + classDef primary fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px classDef secondary fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px classDef tertiary fill:#fff4df,stroke:#b7791f,stroke-width:2px - + class Base primary class LLM,Pipeline secondary class Check,Condense tertiary @@ -4791,9 +4799,9 @@ flowchart LR View["View"] NoOp["NoOpCondenser"] Same["Same View"] - + View --> NoOp --> Same - + style NoOp fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px ``` @@ -4812,7 +4820,7 @@ flowchart LR AddToHistory["Add to History"] NextStep["Next Step: View.from_events()"] NewView["Condensed View"] - + View --> Check Check -->|Yes| Summarize Summarize --> Summary @@ -4820,7 +4828,7 @@ flowchart LR Metadata --> AddToHistory AddToHistory --> NextStep NextStep --> NewView - + style Check fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Summarize fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style NewView fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -4851,9 +4859,9 @@ flowchart LR C2["Condenser 2"] C3["Condenser 3"] Final["Final View"] - + View --> C1 --> C2 --> C3 --> Final - + style C1 fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style C2 fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style C3 fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -4876,9 +4884,9 @@ flowchart TB Check1["condenser.condense(view)"] Trigger1["should_condense()?"] end - + Agent1 --> Build1 --> Check1 --> Trigger1 - + style Check1 fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px ``` @@ -4897,9 +4905,9 @@ flowchart TB NextStep["Next Agent Step"] Trigger2["condense() detects request"] end - + Error --> Request --> NextStep --> Trigger2 - + style Request fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px ``` **Manual Trigger:** @@ -4913,11 +4921,11 @@ flowchart TB %%{init: {"theme": "default", "flowchart": {"nodeSpacing": 30, "rankSpacing": 40}} }%% flowchart TB Start["Agent calls condense(view)"] - + Decision{"should_condense?"} - + ReturnView["Return View
Agent proceeds"] - + Extract["Select Events to Keep/Forget"] Generate["LLM Generates Summary"] Create["Create Condensation Event"] @@ -4927,7 +4935,7 @@ flowchart TB FilterEvents["Filter forgotten events"] InsertSummary["Insert summary at offset"] NewView["New condensed view"] - + Start --> Decision Decision -->|No| ReturnView Decision -->|Yes| Extract @@ -4939,7 +4947,7 @@ flowchart TB NextStep --> FilterEvents FilterEvents --> InsertSummary InsertSummary --> NewView - + style Decision fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Generate fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Create fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -4971,14 +4979,14 @@ flowchart LR View["View
LLMConvertibleEvents"] Convert["events_to_messages()"] LLM["LLM Input"] - + Events --> FromEvents FromEvents --> Filter Filter --> Insert Insert --> View View --> Convert Convert --> LLM - + style View fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style FromEvents fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px ``` @@ -5001,12 +5009,12 @@ flowchart LR Event["Condensation Event
forgotten_event_ids"] Applied["View.from_events()"] New["New View
~60 events + summary"] - + Old -.->|Summarized| Summary Summary --> Event Event --> Applied Applied --> New - + style Event fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Summary fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px ``` @@ -5026,33 +5034,33 @@ flowchart LR flowchart TB View["Current View
120+ events"] Check["Count Events"] - + Compare{"Count >
max_size?"} - + Keep["Keep All Events"] - + Split["Split Events"] Head["Head
First 4 events"] Middle["Middle
~56 events"] Tail["Tail
~56 events"] Summarize["LLM Summarizes Middle"] Result["Head + Summary + Tail
~60 events total"] - + View --> Check Check --> Compare - + Compare -->|Under| Keep Compare -->|Over| Split - + Split --> Head Split --> Middle Split --> Tail - + Middle --> Summarize Head --> Result Summarize --> Result Tail --> Result - + style Compare fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Split fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Summarize fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -5075,13 +5083,13 @@ flowchart LR Condenser["Condenser"] State["Conversation State"] Events["Event Log"] - + Agent -->|"View.from_events()"| State State -->|View| Agent Agent -->|"condense(view)"| Condenser Condenser -->|"View | Condensation"| Agent Agent -->|Adds Condensation| Events - + style Condenser fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Agent fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Events fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -5122,7 +5130,7 @@ The Conversation system has four primary responsibilities: %%{init: {"theme": "default", "flowchart": {"nodeSpacing": 25, "rankSpacing": 35}} }%% flowchart LR User["User Code"] - + subgraph Factory[" "] Entry["Conversation()"] end @@ -5131,26 +5139,26 @@ flowchart LR Local["LocalConversation
Direct execution"] Remote["RemoteConversation
Via agent-server API"] end - + subgraph Core[" "] State["ConversationState
• agent
workspace • stats • ..."] EventLog["ConversationState.events
Event storage"] end - + User --> Entry Entry -.->|LocalWorkspace| Local Entry -.->|RemoteWorkspace| Remote - + Local --> State Remote --> State - + State --> EventLog - + classDef factory fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px classDef impl fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px classDef core fill:#fff4df,stroke:#b7791f,stroke-width:2px classDef service fill:#e9f9ef,stroke:#2f855a,stroke-width:1.5px - + class Entry factory class Local,Remote impl class State,EventLog core @@ -5178,11 +5186,11 @@ flowchart LR Check{Workspace Type?} Local["LocalConversation
Agent runs in-process"] Remote["RemoteConversation
Agent runs via API"] - + Input --> Check Check -->|str or LocalWorkspace| Local Check -->|RemoteWorkspace| Remote - + style Input fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Local fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Remote fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px @@ -5204,13 +5212,13 @@ flowchart TB Start["State Update Request"] Lock["Acquire FIFO Lock"] Decision{New Event?} - + StateOnly["Update State Fields
stats, status, metadata"] EventPath["Append to Event Log
messages, actions, observations"] - + Callback["Trigger Callbacks"] Release["Release Lock"] - + Start --> Lock Lock --> Decision Decision -->|No| StateOnly @@ -5218,7 +5226,7 @@ flowchart TB StateOnly --> Callback EventPath --> Callback Callback --> Release - + style Decision fill:#fff4df,stroke:#b7791f,stroke-width:2px style EventPath fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style StateOnly fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px @@ -5305,13 +5313,13 @@ flowchart LR WS["Workspace"] Tools["Tools"] LLM["LLM"] - + Conv -->|Delegates to| Agent Conv -->|Configures| WS Agent -.->|Updates| Conv Agent -->|Uses| Tools Agent -->|Queries| LLM - + style Conv fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Agent fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style WS fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -5339,52 +5347,52 @@ The **OpenHands Software Agent SDK** is part of the [OpenHands V1](https://openh ## Optional Isolation over Mandatory Sandboxing -**V0 Challenge:** -Every tool call in V0 executed in a sandboxed Docker container by default. While this guaranteed reproducibility and security, it also created friction — the agent and sandbox ran as separate processes, states diverged easily, and multi-tenant workloads could crash each other. +**V0 Challenge:** +Every tool call in V0 executed in a sandboxed Docker container by default. While this guaranteed reproducibility and security, it also created friction — the agent and sandbox ran as separate processes, states diverged easily, and multi-tenant workloads could crash each other. Moreover, with the rise of the Model Context Protocol (MCP), which assumes local execution and direct access to user environments, V0's rigid isolation model became incompatible. -**V1 Principle:** -**Sandboxing should be opt-in, not universal.** -V1 unifies agent and tool execution within a single process by default, aligning with MCP's local-execution model. +**V1 Principle:** +**Sandboxing should be opt-in, not universal.** +V1 unifies agent and tool execution within a single process by default, aligning with MCP's local-execution model. When isolation is needed, the same stack can be transparently containerized, maintaining flexibility without complexity. ## Stateless by Default, One Source of Truth for State -**V0 Challenge:** +**V0 Challenge:** V0 relied on mutable Python objects and dynamic typing, which led to silent inconsistencies — failed session restores, version drift, and non-deterministic behavior. Each subsystem tracked its own transient state, making debugging and recovery painful. -**V1 Principle:** -**Keep everything stateless, with exactly one mutable state.** -All components (agents, tools, LLMs, and configurations) are immutable Pydantic models validated at construction. +**V1 Principle:** +**Keep everything stateless, with exactly one mutable state.** +All components (agents, tools, LLMs, and configurations) are immutable Pydantic models validated at construction. The only mutable entity is the [conversation state](https://github.com/OpenHands/software-agent-sdk/blob/main/openhands-sdk/openhands/sdk/event/conversation_state.py), a single source of truth that enables deterministic replay and robust persistence across sessions or distributed systems. ## Clear Boundaries between Agent and Applications -**V0 Challenge:** -The same codebase powered the CLI, web interface, and integrations (e.g., Github, Gitlab, etc). Over time, application-specific conditionals and prompts polluted the agent core, making it brittle. +**V0 Challenge:** +The same codebase powered the CLI, web interface, and integrations (e.g., Github, Gitlab, etc). Over time, application-specific conditionals and prompts polluted the agent core, making it brittle. Heavy research dependencies and benchmark integrations further bloated production builds. -**V1 Principle:** -**Maintain strict separation of concerns.** -V1 divides the system into stable, isolated layers: the [SDK (agent core)](/sdk/arch/overview#1-sdk-%E2%80%93-openhands-sdk), [tools (set of tools)](/sdk/arch/overview#2-tools-%E2%80%93-openhands-tools), [workspace (sandbox)](/sdk/arch/overview#3-workspace-%E2%80%93-openhands-workspace), and [agent server (server that runs inside sandbox)](/sdk/arch/overview#4-agent-server-%E2%80%93-openhands-agent-server). +**V1 Principle:** +**Maintain strict separation of concerns.** +V1 divides the system into stable, isolated layers: the [SDK (agent core)](/sdk/arch/overview#1-sdk-%E2%80%93-openhands-sdk), [tools (set of tools)](/sdk/arch/overview#2-tools-%E2%80%93-openhands-tools), [workspace (sandbox)](/sdk/arch/overview#3-workspace-%E2%80%93-openhands-workspace), and [agent server (server that runs inside sandbox)](/sdk/arch/overview#4-agent-server-%E2%80%93-openhands-agent-server). Applications communicate with the agent via APIs rather than embedding it directly, ensuring research and production can evolve independently. ## Composable Components for Extensibility -**V0 Challenge:** +**V0 Challenge:** Because agent logic was hard-coded into the core application, extending behavior (e.g., adding new tools or entry points) required branching logic for different entrypoints. This rigidity limited experimentation and discouraged contributions. -**V1 Principle:** -**Everything should be composable and safe to extend.** -Agents are defined as graphs of interchangeable components—tools, prompts, LLMs, and contexts—each described declaratively with strong typing. +**V1 Principle:** +**Everything should be composable and safe to extend.** +Agents are defined as graphs of interchangeable components—tools, prompts, LLMs, and contexts—each described declaratively with strong typing. Developers can reconfigure capabilities (e.g., swap toolsets, override prompts, add delegation logic) without modifying core code, preserving stability while fostering rapid innovation. ### Events @@ -5410,37 +5418,37 @@ The Event System has four primary responsibilities: flowchart TB Base["Event
Base class"] LLMBase["LLMConvertibleEvent
Abstract base"] - + subgraph LLMTypes["LLM-Convertible Events
Visible to the LLM"] Message["MessageEvent
User/assistant text"] Action["ActionEvent
Tool calls"] System["SystemPromptEvent
Initial system prompt"] CondSummary["CondensationSummaryEvent
Condenser summary"] - + ObsBase["ObservationBaseEvent
Base for tool responses"] Observation["ObservationEvent
Tool results"] UserReject["UserRejectObservation
User rejected action"] AgentError["AgentErrorEvent
Agent error"] end - + subgraph Internals["Internal Events
NOT visible to the LLM"] ConvState["ConversationStateUpdateEvent
State updates"] CondReq["CondensationRequest
Request compression"] Cond["Condensation
Compression result"] Pause["PauseEvent
User pause"] end - + Base --> LLMBase Base --> Internals LLMBase --> LLMTypes ObsBase --> Observation ObsBase --> UserReject ObsBase --> AgentError - + classDef primary fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px classDef secondary fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px classDef tertiary fill:#fff4df,stroke:#b7791f,stroke-width:2px - + class Base,LLMBase,Message,Action,SystemPromptEvent primary class ObsBase,Observation,UserReject,AgentError secondary class ConvState,CondReq,Cond,Pause tertiary @@ -5493,12 +5501,12 @@ flowchart LR Group["Group ActionEvents
by llm_response_id"] Convert["Convert to Messages"] LLM["LLM Input"] - + Events --> Filter Filter --> Group Group --> Convert Convert --> LLM - + style Filter fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Group fill:#fff4df,stroke:#b7791f,stroke-width:2px style Convert fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px @@ -5565,13 +5573,13 @@ flowchart LR Conversation["Conversation"] Tools["Tools"] Services["Auxiliary Services"] - + Agent -->|Reads| Events Agent -->|Writes| Events Conversation -->|Manages| Events Tools -->|Creates| Events Events -.->|Stream| Services - + style Events fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Agent fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Conversation fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -5637,37 +5645,37 @@ flowchart TB JSON["JSON Files
config/llm.json"] Code["Programmatic
LLM(...)"] end - + subgraph Core["Core LLM"] Model["LLM Model
Pydantic configuration"] Pipeline["Request Pipeline
Retry, timeout, telemetry"] end - + subgraph Backend["LiteLLM Backend"] Providers["100+ Providers
OpenAI, Anthropic, etc."] end - + subgraph Output["Telemetry"] Usage["Token Usage"] Cost["Cost Tracking"] Latency["Latency Metrics"] end - + Env --> Model JSON --> Model Code --> Model - + Model --> Pipeline Pipeline --> Providers - + Pipeline --> Usage Pipeline --> Cost Pipeline --> Latency - + classDef primary fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px classDef secondary fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px classDef tertiary fill:#fff4df,stroke:#b7791f,stroke-width:2px - + class Model primary class Pipeline secondary class LiteLLM tertiary @@ -5698,10 +5706,10 @@ flowchart LR Code["Python Code"] LLM["LLM(model=...)"] Agent["Agent"] - + Code --> LLM LLM --> Agent - + style LLM fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px ``` @@ -5762,30 +5770,30 @@ If you need to include secrets in JSON, use `llm.model_dump_json(exclude_none=Tr flowchart TB Request["completion() or responses() call"] Validate["Validate Config"] - + Attempt["LiteLLM Request"] Success{"Success?"} - + Retry{"Retries
remaining?"} Wait["Exponential Backoff"] - + Telemetry["Record Telemetry"] Response["Return Response"] Error["Raise Error"] - + Request --> Validate Validate --> Attempt Attempt --> Success - + Success -->|Yes| Telemetry Success -->|No| Retry - + Retry -->|Yes| Wait Retry -->|No| Error - + Wait --> Attempt Telemetry --> Response - + style Attempt fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Retry fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Telemetry fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -5809,37 +5817,37 @@ In addition to the standard chat completion API, the LLM system supports [OpenAI %%{init: {"theme": "default", "flowchart": {"nodeSpacing": 30, "rankSpacing": 40}} }%% flowchart TB Check{"Model supports
Responses API?"} - + subgraph Standard["Standard Path"] ChatFormat["Format as
Chat Messages"] ChatCall["litellm.completion()"] end - + subgraph ResponsesPath["Responses Path"] RespFormat["Format as
instructions + input[]"] RespCall["litellm.responses()"] end - + ChatResponse["ModelResponse"] RespResponse["ResponsesAPIResponse"] - + Parse["Parse to Message"] Return["LLMResponse"] - + Check -->|No| ChatFormat Check -->|Yes| RespFormat - + ChatFormat --> ChatCall RespFormat --> RespCall - + ChatCall --> ChatResponse RespCall --> RespResponse - + ChatResponse --> Parse RespResponse --> Parse - + Parse --> Return - + style RespFormat fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style RespCall fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px ``` @@ -5866,7 +5874,7 @@ Software Agent SDK uses LiteLLM for provider abstraction: flowchart TB SDK["Software Agent SDK"] LiteLLM["LiteLLM"] - + subgraph Providers["100+ Providers"] OpenAI["OpenAI"] Anthropic["Anthropic"] @@ -5874,14 +5882,14 @@ flowchart TB Azure["Azure"] Others["..."] end - + SDK --> LiteLLM LiteLLM --> OpenAI LiteLLM --> Anthropic LiteLLM --> Google LiteLLM --> Azure LiteLLM --> Others - + style LiteLLM fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style SDK fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px ``` @@ -5928,23 +5936,23 @@ LLM requests automatically collect metrics: %%{init: {"theme": "default", "flowchart": {"nodeSpacing": 30}} }%% flowchart LR Request["LLM Request"] - + subgraph Metrics Tokens["Token Counts
Input/Output"] Cost["Cost
USD"] Latency["Latency
ms"] end - + Events["Event Log"] - + Request --> Tokens Request --> Cost Request --> Latency - + Tokens --> Events Cost --> Events Latency --> Events - + style Metrics fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Events fill:#fff4df,stroke:#b7791f,stroke-width:2px ``` @@ -5987,13 +5995,13 @@ flowchart LR Events["Events"] Security["Security Analyzer"] Condenser["Context Condenser"] - + Agent -->|Uses| LLM LLM -->|Records| Events Security -.->|Optional| LLM Condenser -.->|Optional| LLM Conversation -->|Provides context| Agent - + style LLM fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Agent fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Events fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -6039,38 +6047,38 @@ flowchart TB Sync["MCPClient
Sync/Async bridge"] Async["AsyncMCPClient
FastMCP base"] end - + subgraph Bridge["Tool Bridge"] Def["MCPToolDefinition
Schema conversion"] Exec["MCPToolExecutor
Execution handler"] end - + subgraph Integration["Agent Integration"] Action["MCPToolAction
Dynamic model"] Obs["MCPToolObservation
Result wrapper"] end - + subgraph External["External"] Server["MCP Server
stdio/HTTP"] Tools["External Tools"] end - + Sync --> Async Async --> Server - + Server --> Def Def --> Exec - + Exec --> Action Action --> Server Server --> Obs - + Server -.->|Spawns| Tools - + classDef primary fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px classDef secondary fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px classDef tertiary fill:#fff4df,stroke:#b7791f,stroke-width:2px - + class Sync,Async primary class Def,Exec secondary class Action,Obs tertiary @@ -6101,14 +6109,14 @@ flowchart TB Async["Async MCP Call"] Server["MCP Server"] Result["Result"] - + Sync --> Bridge Bridge --> Executor Executor --> Async Async --> Server Server --> Result Result --> Sync - + style Bridge fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Executor fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Async fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -6159,23 +6167,23 @@ flowchart TB Config["MCP Config"] Spawn["Spawn Server"] List["List Tools"] - + subgraph Convert["Convert Each Tool"] Schema["MCP Schema"] Action["Generate Action Model"] Def["Create ToolDefinition"] end - + Register["Register in ToolRegistry"] - + Config --> Spawn Spawn --> List List --> Schema - + Schema --> Action Action --> Def Def --> Register - + style Spawn fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Action fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Register fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -6201,11 +6209,11 @@ flowchart LR Parse["Parse Parameters"] Model["Dynamic Pydantic Model
MCPToolAction"] Def["ToolDefinition
SDK format"] - + MCP --> Parse Parse --> Model Model --> Def - + style Parse fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Model fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px ``` @@ -6254,15 +6262,15 @@ flowchart TB Agent["Agent generates action"] Action["MCPToolAction"] Executor["MCPToolExecutor"] - + Convert["Convert to MCP format"] Call["MCP call_tool"] Server["MCP Server"] - + Result["MCP Result"] Obs["MCPToolObservation"] Return["Return to Agent"] - + Agent --> Action Action --> Executor Executor --> Convert @@ -6271,7 +6279,7 @@ flowchart TB Server --> Result Result --> Obs Obs --> Return - + style Executor fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Call fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Obs fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -6297,10 +6305,10 @@ flowchart LR Executor["MCPToolExecutor"] Client["MCP Client"] Name["tool_name"] - + Executor -->|Uses| Client Executor -->|Knows| Name - + style Executor fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Client fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px ``` @@ -6324,32 +6332,32 @@ flowchart TB Spawn["Spawn MCP Servers"] Discover["Discover Tools"] Register["Register Tools"] - + Ready["Agent Ready"] - + Step["Agent Step"] LLM["LLM Tool Call"] Execute["Execute MCP Tool"] Result["Return Observation"] - + End["End Conversation"] Cleanup["Close MCP Clients"] - + Load --> Start Start --> Spawn Spawn --> Discover Discover --> Register Register --> Ready - + Ready --> Step Step --> LLM LLM --> Execute Execute --> Result Result --> Step - + Step --> End End --> Cleanup - + style Spawn fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Execute fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Cleanup fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -6372,22 +6380,22 @@ MCP tools can include metadata hints for agents: %%{init: {"theme": "default", "flowchart": {"nodeSpacing": 30}} }%% flowchart LR Tool["MCP Tool"] - + subgraph Annotations ReadOnly["readOnlyHint"] Destructive["destructiveHint"] Progress["progressEnabled"] end - + Security["Security Analysis"] - + Tool --> ReadOnly Tool --> Destructive Tool --> Progress - + ReadOnly --> Security Destructive --> Security - + style Destructive fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Security fill:#fff4df,stroke:#b7791f,stroke-width:2px ``` @@ -6414,12 +6422,12 @@ flowchart LR Tools["Tool Registry"] Agent["Agent"] Security["Security"] - + Skills -->|Configures| MCP MCP -->|Registers| Tools Agent -->|Uses| Tools MCP -->|Provides hints| Security - + style MCP fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Skills fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Agent fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -6478,7 +6486,7 @@ graph TB end SDK[Software Agent SDK
openhands.sdk + tools + workspace] - + subgraph External["External Services"] LLM[LLM Providers
OpenAI, Anthropic, etc.] Runtime[Runtime Services
Docker, Remote API, etc.] @@ -6487,14 +6495,14 @@ graph TB UI --> SDK CLI --> SDK Custom --> SDK - + SDK --> LLM SDK --> Runtime - + classDef interface fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px classDef sdk fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px classDef external fill:#fff4df,stroke:#b7791f,stroke-width:2px - + class UI,CLI,Custom interface class SDK sdk class LLM,Runtime external @@ -6531,9 +6539,9 @@ pip install openhands-sdk openhands-tools flowchart LR SDK["openhands.sdk
Agent · LLM · Conversation
+ LocalWorkspace"]:::sdk Tools["openhands.tools
BashTool · FileEditor · GrepTool · …"]:::tools - + SDK -->|uses| Tools - + classDef sdk fill:#e8f3ff,stroke:#2b6cb0,color:#0f2a45,stroke-width:2px,rx:8,ry:8 classDef tools fill:#e9f9ef,stroke:#2f855a,color:#14532d,stroke-width:2px,rx:8,ry:8 ``` @@ -6556,31 +6564,31 @@ pip install openhands-sdk openhands-tools openhands-workspace openhands-agent-se ```mermaid %%{init: {"theme": "default", "flowchart": {"nodeSpacing": 20, "rankSpacing": 30}} }%% flowchart LR - + WSBase["openhands.sdk
Base Classes:
Workspace · Local · Remote"]:::sdk - + subgraph WS[" "] direction LR Docker["openhands.workspace DockerWorkspace
extends RemoteWorkspace"]:::ws Remote["openhands.workspace RemoteAPIWorkspace
extends RemoteWorkspace"]:::ws end - + Server["openhands.agent_server
FastAPI + WebSocket"]:::server Agent["openhands.sdk
Agent · LLM · Conversation"]:::sdk Tools["openhands.tools
BashTool · FileEditor · …"]:::tools - + WSBase -.->|extended by| Docker WSBase -.->|extended by| Remote Docker -->|spawns container with| Server Remote -->|connects via HTTP to| Server Server -->|runs| Agent Agent -->|uses| Tools - + classDef sdk fill:#e8f3ff,stroke:#2b6cb0,color:#0f2a45,stroke-width:1.1px,rx:8,ry:8 classDef ws fill:#fff4df,stroke:#b7791f,color:#5b3410,stroke-width:1.1px,rx:8,ry:8 classDef server fill:#f3e8ff,stroke:#7c3aed,color:#3b2370,stroke-width:1.1px,rx:8,ry:8 classDef tools fill:#e9f9ef,stroke:#2f855a,color:#14532d,stroke-width:1.1px,rx:8,ry:8 - + style WS stroke:#b7791f,stroke-width:1.5px,stroke-dasharray: 4 3,rx:8,ry:8,fill:none ``` @@ -6674,7 +6682,7 @@ sequenceDiagram participant Agent participant LLM participant Tool - + You->>Conversation: "Create hello.txt" Conversation->>Agent: Process message Agent->>LLM: What should I do? @@ -6699,17 +6707,17 @@ graph TB subgraph "Your Code (Unchanged)" Code["Agent + Tools + LLM"] end - + subgraph "Deployment Options" Local["Local
Direct execution"] Docker["Docker
Containerized"] Remote["Remote
Multi-user server"] end - + Code -->|LocalWorkspace| Local Code -->|DockerWorkspace| Docker Code -->|RemoteAPIWorkspace| Remote - + style Code fill:#e1f5fe style Local fill:#e8f5e8 style Docker fill:#e8f5e8 @@ -6776,18 +6784,18 @@ The SDK package handles: ```mermaid graph TB Conv[Conversation
Lifecycle Manager] --> Agent[Agent
Reasoning Loop] - + Agent --> LLM[LLM
Language Model] Agent --> Tools[Tool System
Capabilities] Agent --> Micro[Skills
Behavior Modules] Agent --> Cond[Condenser
Memory Manager] - + Tools --> Workspace[Workspace
Execution] - + Conv --> Events[Events
Communication] Tools --> MCP[MCP
External Tools] Workspace --> Security[Security
Validation] - + style Conv fill:#e1f5fe style Agent fill:#f3e5f5 style LLM fill:#e8f5e8 @@ -6924,7 +6932,7 @@ graph TB 2. **Observation**: Output schema (what the tool returns) 3. **ToolExecutor**: Logic that transforms Action → Observation -**Why this pattern?** +**Why this pattern?** - Type safety catches errors early - LLMs get accurate schemas for tool calling - Tools are testable in isolation @@ -7242,46 +7250,46 @@ flowchart TB subgraph Interface["Abstract Interface"] Base["SecurityAnalyzerBase
Abstract analyzer"] end - + subgraph Implementations["Concrete Analyzers"] LLM["LLMSecurityAnalyzer
Inline risk prediction"] NoOp["NoOpSecurityAnalyzer
No analysis"] end - + subgraph Risk["Risk Levels"] Low["LOW
Safe operations"] Medium["MEDIUM
Moderate risk"] High["HIGH
Dangerous ops"] Unknown["UNKNOWN
Unanalyzed"] end - + subgraph Policy["Confirmation Policy"] Check["should_require_confirmation()"] Mode["Confirmation Mode"] Decision["Require / Allow"] end - + Base --> LLM Base --> NoOp - + Implementations --> Low Implementations --> Medium Implementations --> High Implementations --> Unknown - + Low --> Check Medium --> Check High --> Check Unknown --> Check - + Check --> Mode Mode --> Decision - + classDef primary fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px classDef secondary fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px classDef tertiary fill:#fff4df,stroke:#b7791f,stroke-width:2px classDef danger fill:#ffe8e8,stroke:#dc2626,stroke-width:2px - + class Base primary class LLM secondary class High danger @@ -7307,20 +7315,20 @@ Security analyzers return one of four risk levels: flowchart TB Action["ActionEvent"] Analyze["Security Analyzer"] - + subgraph Levels["Risk Levels"] Low["LOW
Read-only, safe"] Medium["MEDIUM
Modify files"] High["HIGH
Delete, execute"] Unknown["UNKNOWN
Not analyzed"] end - + Action --> Analyze Analyze --> Low Analyze --> Medium Analyze --> High Analyze --> Unknown - + style Low fill:#d1fae5,stroke:#10b981,stroke-width:2px style Medium fill:#fef3c7,stroke:#f59e0b,stroke-width:2px style High fill:#ffe8e8,stroke:#dc2626,stroke-width:2px @@ -7351,13 +7359,13 @@ flowchart TB Extract["Extract security_risk
from arguments"] ActionEvent["ActionEvent
with security_risk set"] Analyzer["LLMSecurityAnalyzer
returns security_risk"] - + Schema --> LLM LLM --> ToolCall ToolCall --> Extract Extract --> ActionEvent ActionEvent --> Analyzer - + style Schema fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Extract fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Analyzer fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -7400,9 +7408,9 @@ flowchart LR Action["ActionEvent"] NoOp["NoOpSecurityAnalyzer"] Unknown["SecurityRisk.UNKNOWN"] - + Action --> NoOp --> Unknown - + style NoOp fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px ``` @@ -7433,20 +7441,20 @@ flowchart TB CheckUnknown{"Risk ==
UNKNOWN?"} UseConfirmUnknown{"confirm_unknown
setting?"} CheckThreshold{"risk.is_riskier
(threshold)?"} - + Confirm["Require Confirmation"] Allow["Allow Execution"] - + Risk --> CheckUnknown CheckUnknown -->|Yes| UseConfirmUnknown CheckUnknown -->|No| CheckThreshold - + UseConfirmUnknown -->|True| Confirm UseConfirmUnknown -->|False| Allow - + CheckThreshold -->|Yes| Confirm CheckThreshold -->|No| Allow - + style CheckUnknown fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Confirm fill:#ffe8e8,stroke:#dc2626,stroke-width:2px style Allow fill:#d1fae5,stroke:#10b981,stroke-width:2px @@ -7503,12 +7511,12 @@ flowchart LR Conversation["Conversation"] Tools["Tools"] MCP["MCP Tools"] - + Agent -->|Validates actions| Security Security -->|Checks| Tools Security -->|Uses hints| MCP Conversation -->|Pauses for confirmation| Agent - + style Security fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Agent fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Conversation fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -7554,47 +7562,47 @@ flowchart TB Knowledge["Knowledge Skill
trigger: KeywordTrigger"] Task["Task Skill
trigger: TaskTrigger"] end - + subgraph Triggers["Trigger Evaluation"] Always["Always Active
Repository guidelines"] Keyword["Keyword Match
String matching on user messages"] TaskMatch["Keyword Match + Inputs
Same as KeywordTrigger + user inputs"] end - + subgraph Content["Skill Content"] Markdown["Markdown with Frontmatter"] Dynamic["Dynamic Commands
!`command` execution"] MCPTools["MCP Tools Config
Repo skills only"] Inputs["Input Metadata
Task skills only"] end - + subgraph Integration["Agent Integration"] Context["Agent Context"] Prompt["System Prompt"] end - + Repo --> Always Knowledge --> Keyword Task --> TaskMatch - + Always --> Markdown Keyword --> Markdown TaskMatch --> Markdown - + Markdown -.->|Optional| Dynamic Repo -.->|Optional| MCPTools Task -.->|Requires| Inputs - + Markdown --> Context Dynamic --> Context MCPTools --> Context Context --> Prompt - + classDef primary fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px classDef secondary fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px classDef tertiary fill:#fff4df,stroke:#b7791f,stroke-width:2px classDef dynamic fill:#e9f9ef,stroke:#2f855a,stroke-width:2px - + class Repo,Knowledge,Task primary class Always,Keyword,TaskMatch secondary class Context tertiary @@ -7627,11 +7635,11 @@ flowchart LR Parse["Parse Frontmatter"] Skill["Skill(trigger=None)"] Context["Always in Context"] - + File --> Parse Parse --> Skill Skill --> Context - + style Skill fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Context fill:#fff4df,stroke:#b7791f,stroke-width:2px ``` @@ -7664,13 +7672,13 @@ flowchart TB Activate["Activate Skill"] Skip["Skip Skill"] Context["Add to Context"] - + User --> Check Check --> Match Match -->|Yes| Activate Match -->|No| Skip Activate --> Context - + style Check fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Activate fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px ``` @@ -7704,13 +7712,13 @@ flowchart TB Template["Apply Template"] Context["Add to Context"] Skip["Skip Skill"] - + User --> Match Match -->|Yes| Inputs Match -->|No| Skip Inputs --> Template Template --> Context - + style Match fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Template fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px ``` @@ -7744,35 +7752,35 @@ Skills are evaluated at different points in the agent lifecycle: %%{init: {"theme": "default", "flowchart": {"nodeSpacing": 30, "rankSpacing": 40}} }%% flowchart TB Start["Agent Step Start"] - + Repo["Check Repository Skills
trigger: None"] AddRepo["Always Add to Context"] - + Message["Check User Message"] Keyword["Match Keyword Triggers"] AddKeyword["Add Matched Skills"] - + TaskType["Check Task Type"] TaskMatch["Match Task Triggers"] AddTask["Add Task Skill"] - + Build["Build Agent Context"] - + Start --> Repo Repo --> AddRepo - + Start --> Message Message --> Keyword Keyword --> AddKeyword - + Start --> TaskType TaskType --> TaskMatch TaskMatch --> AddTask - + AddRepo --> Build AddKeyword --> Build AddTask --> Build - + style Repo fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Keyword fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style TaskMatch fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -7799,11 +7807,11 @@ flowchart LR MCPConfig["mcp_tools Config"] Client["MCP Client"] Tools["Tool Registry"] - + Skill -->|Contains| MCPConfig MCPConfig -->|Spawns| Client Client -->|Registers| Tools - + style Skill fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style MCPConfig fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Tools fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -7892,12 +7900,12 @@ flowchart LR Context["Agent Context"] Agent["Agent"] MCP["MCP Client"] - + Skills -->|Injects content| Context Skills -.->|Spawns tools| MCP Context -->|System prompt| Agent MCP -->|Tool| Agent - + style Skills fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Context fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Agent fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -7943,7 +7951,7 @@ flowchart TB Observation["Observation
Output schema"] Executor["Executor
Business logic"] end - + subgraph Framework["Tool Framework"] Base["ToolBase
Abstract base"] Impl["Tool Implementation
Concrete tool"] @@ -7955,7 +7963,7 @@ flowchart TB ToolSpec["Tool Spec
name + params"] Base -.->|Extends| Impl - + ToolSpec -->|resolve_tool| Registry Registry -->|Create instances| Impl Impl -->|Available in| Agent @@ -7964,11 +7972,11 @@ flowchart TB Agent -->|Parse & validate| Action Agent -->|Execute via Tool.\_\_call\_\_| Executor Executor -->|Return| Observation - + classDef primary fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px classDef secondary fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px classDef tertiary fill:#fff4df,stroke:#b7791f,stroke-width:2px - + class Base primary class Action,Observation,Executor secondary class Registry tertiary @@ -8002,14 +8010,14 @@ flowchart TB WrapObs["ObservationEvent
wraps Observation"] Error["AgentErrorEvent"] end - + subgraph ToolSystem["Tool System"] ActionType["Action
Pydantic model"] ToolCall2["tool.\_\_call\_\_(action)
type-safe execution"] Execute["ToolExecutor
business logic"] ObsType["Observation
Pydantic model"] end - + ToolCall --> ParseJSON ParseJSON -->|Valid JSON| CreateAction ParseJSON -->|Invalid JSON| Error @@ -8020,7 +8028,7 @@ flowchart TB ToolCall2 --> Execute Execute --> ObsType ObsType --> WrapObs - + style ToolSystem fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Agent fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style ActionType fill:#ddd6fe,stroke:#7c3aed,stroke-width:2px @@ -8047,11 +8055,11 @@ flowchart LR Obs["Define Observation
with to_llm_content"] Exec["Define Executor
stateless logic"] Tool["ToolDefinition(...,
executor=Executor())"] - + Action --> Tool Obs --> Tool Exec --> Tool - + style Tool fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px ``` @@ -8073,12 +8081,12 @@ flowchart LR Exec["Define Executor
with \_\_init\_\_ and state"] Subclass["class MyTool(ToolDefinition)
with create() method"] Instance["Return [MyTool(...,
executor=instance)]"] - + Action --> Subclass Obs --> Subclass Exec --> Subclass Subclass --> Instance - + style Instance fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px ``` @@ -8096,21 +8104,21 @@ flowchart TB P1E["Define ToolExecutor
with \_\_call\_\_()"] P1T["ToolDefinition(...,
executor=Executor())"] end - + subgraph Pattern2["Pattern 2: Subclass with Factory"] P2A["Define Action/Observation
with visualize/to_llm_content"] P2E["Define Stateful ToolExecutor
with \_\_init\_\_() and \_\_call\_\_()"] P2C["class MyTool(ToolDefinition)
@classmethod create()"] P2I["Return [MyTool(...,
executor=instance)]"] end - + P1A --> P1E P1E --> P1T - + P2A --> P2E P2E --> P2C P2C --> P2I - + style P1T fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style P2I fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px ``` @@ -8154,20 +8162,20 @@ The registry enables **dynamic tool discovery** and instantiation from tool spec %%{init: {"theme": "default", "flowchart": {"nodeSpacing": 30}} }%% flowchart LR ToolSpec["Tool Spec
name + params"] - + subgraph Registry["Tool Registry"] Resolver["Resolver
name → factory"] Factory["Factory
create(params)"] end - + Instance["Tool Instance
with executor"] Agent["Agent"] - + ToolSpec -->|"resolve_tool(spec)"| Resolver Resolver -->|Lookup factory| Factory Factory -->|"create(**params)"| Instance Instance -->|Used by| Agent - + style Registry fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Factory fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px ``` @@ -8231,18 +8239,18 @@ flowchart TB Server["MCP Server
stdio/HTTP"] ExtTools["External Tools"] end - + subgraph Bridge["MCP Integration Layer"] MCPClient["MCPClient
Sync/Async bridge"] Convert["Schema Conversion
MCP → MCPToolDefinition"] MCPExec["MCPToolExecutor
Bridges to MCP calls"] end - + subgraph Agent["Agent System"] ToolsMap["tools_map
str -> ToolDefinition"] AgentLogic["Agent Execution"] end - + Server -.->|Spawns| ExtTools MCPClient --> Server Server --> Convert @@ -8251,11 +8259,11 @@ flowchart TB ToolsMap --> AgentLogic AgentLogic -->|Tool call| MCPExec MCPExec --> MCPClient - + classDef primary fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px classDef secondary fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px classDef external fill:#fff4df,stroke:#b7791f,stroke-width:2px - + class MCPClient primary class Convert,MCPExec secondary class Server,ExtTools external @@ -8284,13 +8292,13 @@ flowchart LR Loop["Background Event Loop"] Async["Async MCP Call"] Result["Return Result"] - + Sync --> Bridge Bridge --> Loop Loop --> Async Async --> Result Result --> Sync - + style Bridge fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Loop fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px ``` @@ -8311,16 +8319,16 @@ flowchart TB Config["MCP Server Config
command + args"] Spawn["Spawn Server Process
MCPClient"] List["List Available Tools
client.list_tools()"] - + subgraph Convert["For Each MCP Tool"] Store["Store MCP metadata
name, description, inputSchema"] CreateExec["Create MCPToolExecutor
bound to tool + client"] Def["Create MCPToolDefinition
generic MCPToolAction type"] end - + Register["Add to Agent's tools_map
bypasses ToolRegistry"] Ready["Tools Available
Dynamic models created on-demand"] - + Config --> Spawn Spawn --> List List --> Store @@ -8328,7 +8336,7 @@ flowchart TB CreateExec --> Def Def --> Register Register --> Ready - + style Spawn fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Def fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Register fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -8389,18 +8397,18 @@ flowchart TB Native["Native Tools"] MCP["MCP Tools"] end - + Registry["Tool Registry
resolve_tool"] ToolsMap["Agent.tools_map
Merged tool dict"] - + subgraph AgentSystem["Agent System"] Agent["Agent Logic"] LLM["LLM"] end - + Security["Security Analyzer"] Conversation["Conversation State"] - + Native -->|register_tool| Registry Registry --> ToolsMap MCP -->|create_mcp_tools| ToolsMap @@ -8408,7 +8416,7 @@ flowchart TB Agent -->|Execute tools| ToolsMap ToolsMap -.->|Action risk| Security ToolsMap -.->|Read state| Conversation - + style ToolsMap fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Agent fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style Security fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -8455,38 +8463,38 @@ flowchart TB subgraph Interface["Abstract Interface"] Base["BaseWorkspace
Abstract base class"] end - + subgraph Implementations["Concrete Implementations"] Local["LocalWorkspace
Direct subprocess"] Remote["RemoteWorkspace
HTTP API calls"] end - + subgraph Operations["Core Operations"] Command["execute_command()"] Upload["file_upload()"] Download["file_download()"] Context["__enter__ / __exit__"] end - + subgraph Targets["Execution Targets"] Process["Local Process"] Container["Docker Container"] Server["Remote Server"] end - + Base --> Local Base --> Remote - + Base -.->|Defines| Operations - + Local --> Process Remote --> Container Remote --> Server - + classDef primary fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px classDef secondary fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px classDef tertiary fill:#fff4df,stroke:#b7791f,stroke-width:2px - + class Base primary class Local,Remote secondary class Command,Upload tertiary @@ -8523,21 +8531,21 @@ flowchart TB %%{init: {"theme": "default", "flowchart": {"nodeSpacing": 30, "rankSpacing": 40}} }%% flowchart LR Tool["Tool invokes
execute_command()"] - + Decision{"Workspace
type?"} - + LocalExec["subprocess.run()
Direct execution"] RemoteExec["POST /command
HTTP API"] - + Result["CommandResult
stdout, stderr, exit_code"] - + Tool --> Decision Decision -->|Local| LocalExec Decision -->|Remote| RemoteExec - + LocalExec --> Result RemoteExec --> Result - + style Decision fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style LocalExec fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style RemoteExec fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -8581,16 +8589,16 @@ The SDK provides remote workspace implementations in `openhands-workspace` packa %%{init: {"theme": "default", "flowchart": {"nodeSpacing": 50}} }%% flowchart TB Base["RemoteWorkspace
SDK base class"] - + Docker["DockerWorkspace
Auto-spawn containers"] API["RemoteAPIWorkspace
Connect to existing server"] - + Base -.->|Extended by| Docker Base -.->|Extended by| API - + Docker -->|Creates| Container["Docker Container
with agent-server"] API -->|Connects| Server["Remote Agent Server"] - + style Base fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Docker fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px style API fill:#fff4df,stroke:#b7791f,stroke-width:2px @@ -8604,7 +8612,7 @@ flowchart TB | **DockerWorkspace** | Spawn container | Container | Multi-user, untrusted code | | **RemoteAPIWorkspace** | Connect to URL | Remote server | Distributed systems, cloud | -**Source:** +**Source:** - **DockerWorkspace**: [`openhands-workspace/openhands/workspace/docker`](https://github.com/OpenHands/software-agent-sdk/tree/main/openhands-workspace/openhands/workspace/docker) - **RemoteAPIWorkspace**: [`openhands-workspace/openhands/workspace/remote_api`](https://github.com/OpenHands/software-agent-sdk/tree/main/openhands-workspace/openhands/workspace/remote_api) @@ -8618,10 +8626,10 @@ flowchart LR Workspace["Workspace"] Conversation["Conversation"] AgentServer["Agent Server"] - + Conversation -->|Configures| Workspace Workspace -.->|Remote type| AgentServer - + style Workspace fill:#f3e8ff,stroke:#7c3aed,stroke-width:2px style Conversation fill:#e8f3ff,stroke:#2b6cb0,stroke-width:2px ``` @@ -9805,7 +9813,7 @@ def get_planning_tools() -> list[Tool]: The planning agent uses: - **GlobTool**: For discovering files and directories matching patterns -- **GrepTool**: For searching specific content across files +- **GrepTool**: For searching specific content across files - **PlanningFileEditorTool**: For writing structured plans to `PLAN.md` only This read-only approach (except for `PLAN.md`) keeps the agent focused on analysis without implementation distractions. @@ -11767,6 +11775,17 @@ cd agent-sdk uv run python examples/02_remote_agent_server/10_cloud_workspace_share_credentials.py ``` + +## Settings and Secrets API Examples + +The remote agent-server examples also include end-to-end scripts for settings-backed secrets and authenticated LLM configuration: + +- [examples/02_remote_agent_server/12_settings_and_secrets_api.py](https://github.com/OpenHands/software-agent-sdk/blob/main/examples/02_remote_agent_server/12_settings_and_secrets_api.py) demonstrates storing secrets through the Settings and Secrets API, referencing them with `LookupSecret`, and cleaning them up after use. +- [examples/02_remote_agent_server/13_workspace_get_llm.py](https://github.com/OpenHands/software-agent-sdk/blob/main/examples/02_remote_agent_server/13_workspace_get_llm.py) demonstrates configuring LLM settings on an authenticated agent-server and retrieving them through `RemoteWorkspace.get_llm()`. + + + + ## Next Steps - **[API-based Sandbox](/sdk/guides/agent-server/api-sandbox)** - Connect to Runtime API service @@ -12013,7 +12032,7 @@ ENV PYTHONPATH="/app:${PYTHONPATH}" This example is available on GitHub: [examples/02_remote_agent_server/06_custom_tool/](https://github.com/OpenHands/software-agent-sdk/tree/main/examples/02_remote_agent_server/06_custom_tool) -```python icon="python" expandable examples/02_remote_agent_server/06_custom_tool/custom_tool_example.py +```python icon="python" expandable examples/02_remote_agent_server/06_custom_tool/main.py """Example: Using custom tools with remote agent server. This example demonstrates how to use custom tools with a remote agent server @@ -12292,7 +12311,7 @@ The docker sandboxed agent server demonstrates how to run agents in isolated Doc This provides complete isolation from the host system, making it ideal for production deployments, testing, and executing untrusted code safely. -Use `DockerWorkspace` with a pre-built agent server image for the fastest startup. When you need to build your own image from a base image, switch to `DockerDevWorkspace`. +Use `DockerWorkspace` with a pre-built agent server image for the fastest startup. When you need to build your own image from a base image, switch to `DockerDevWorkspace`. the Docker sandbox image ships with features configured in the [Dockerfile](https://github.com/OpenHands/software-agent-sdk/blob/main/openhands-agent-server/openhands/agent_server/docker/Dockerfile) (e.g., secure defaults and services like VSCode and VNC exposed behind well-defined ports), which are not available in the local (non-Docker) agent server. @@ -12779,7 +12798,7 @@ agent = get_default_agent( When `cli_mode=False`, the agent gains access to browser automation tools for web interaction. -When VNC is available and `extra_ports=True`, the browser will be opened in the VNC desktop to visualize agent's work. You can watch the browser in real-time via VNC. Demo video: +When VNC is available and `extra_ports=True`, the browser will be opened in the VNC desktop to visualize agent's work. You can watch the browser in real-time via VNC. Demo video:
- - Run OpenHands locally with a web-based interface. Bring your own LLM and API key. + + Install Agent Canvas from npm and run it from your terminal. - - Full control over your environment - - Works offline - - Docker-based setup + - Local and remote backend workflows + - Automations, skills, and MCP support + - Self-hosted friendly @@ -38266,7 +39289,7 @@ Each skill file may include frontmatter that provides additional information. In |----------|---------------|---------------------|----------------|---------------| | **CLI** | ✅ Full Support | `~/.agents/skills/` (user-level) and `.agents/skills/` (repo-level) | File-based markdown | [Skills Overview](/overview/skills) | | **SDK** | ✅ Full Support | Programmatic `Skill` objects | Code-based configuration | [SDK Skills Guide](/sdk/guides/skill) | -| **Local GUI** | ✅ Full Support | `.agents/skills/` + UI | File-based with UI management | [Local Setup](/openhands/usage/run-openhands/local-setup) | +| **Agent Canvas** | ✅ Full Support | `.agents/skills/` + UI | File-based with UI management | [Customize and Settings](/openhands/usage/agent-canvas/customize-and-settings) | | **OpenHands Cloud** | ✅ Full Support | Cloud UI + repository integration | Managed skill library | [Cloud UI](/openhands/usage/cloud/cloud-ui) | ## Platform-Specific Differences @@ -38286,11 +39309,11 @@ Each skill file may include frontmatter that provides additional information. In - Integration with custom workflows - Full control over skill lifecycle - - - Visual skill management through UI - - File-based storage with GUI editing + + - Visual skill management through `Customize` + - File-based storage with UI editing - Real-time skill status display - - Drag-and-drop skill organization + - Backend-aware customization workflows - Cloud-based skill library management @@ -38642,60 +39665,180 @@ Enterprise customers receive: - [SDK Documentation](/sdk/index) — Build custom agents with the OpenHands SDK - [Pricing](https://openhands.dev/pricing) — Compare all OpenHands plans +### Analytics +Source: https://docs.openhands.dev/enterprise/analytics.md + +This guide walks you through setting up and using Laminar for Analytics in OpenHands Enterprise. +You'll opt into Analytics and configure conversations to automatically send traces to Laminar. + +## Who This Is For + +This guide is for users who want to explore analytics on their OpenHands Enterprise conversations. + +### Why Laminar? + +[Laminar](https://laminar.sh/) is an open source observability platform for AI agents like OpenHands. + +Use Laminar to view your conversation traces including prompts, tool calls, and answers. A trace is a record of what your agent did. + +Laminar can help you see where the agent went wrong. From traces, you can create signals. A signal is a natural language instruction to extract structured data from traces. Use signals to analyze recurring behavior across traces. You can then create better situations for prompting and measure them in Laminar. You can also analyze and improve your skills. + +For example, you can view all conversation traces related to a specific skill. + +Laminar can help you answer the following questions: +- On a trace, did the agent do a good job using the skill? +- On another trace, did the agent do a bad job? + +For more information on evaluating skills, see [Evaluating Agent Skills](https://www.openhands.dev/blog/evaluating-agent-skills). + +### Prerequisites + +Before you begin, make sure you completed the [Quick Start guide](/enterprise/quick-start). + +## Enable Analytics + +You should see an **Analytics Configuration** section on the application configuration page. + +Check the **Enable Analytics** box to have the installer set up and configure Laminar for analytics. + +![Configure Analytics](./images/laminar-configure-analytics.png) + +## Deploy + +OpenHands will begin deploying. You can expect the deployment status to transition from +**Missing** to **Unavailable** to **Ready**. This typically takes 10-15 minutes. + +![Deployment in progress](./images/laminar-deploy-in-progress.png) + +Click **Details** next to the deployment status to monitor individual resources. Resources +shown in orange are still deploying -- wait until all resources are ready. + +![Deployment status details](./images/laminar-deployment-status-details.png) + +## Access Laminar UI + +Once the deployment status shows **Ready**, navigate to `https://analytics.app.`. + +Click the **Continue with Keycloak** button: + +![Laminar Keycloak Auth](./images/laminar-keycloak-auth.png) + +## Create a Laminar project + +![Laminar Create Project](./images/laminar-create-project.png) + +Once a project has been created, Laminar is ready to listen for traces. + +![Laminar Listen Traces](./images/laminar-listen-traces.png) + +## Create an ingest only API Key + +Important: Always use ingest API keys when deploying. + +Create a key with ther right permissions. Ingest only keys are recommended as they only have write access to write traces. They cannot be used to read data. + +![Configure Laminar Ingest Only Key](./images/laminar-ingest-only-key.png) + +## Set Laminar Project API Key to enable automatic conversation traces + +Set the ingest only key as the Laminar Project API Key in the Admin Console configuration: + +![Configure Laminar Project API Key](./images/laminar-configure-key.png) + +Click **Save config**. + +## Deploy Updated Configuration + +Deploy the config change after setting the Laminar Project API Key in the Admin Console. + +![Laminar Deploy Again](./images/laminar-deploy-again.png) + +Wait for the deployment to complete. + +## Start a conversation + +Navigate to the OpenHands UI at `https://app.`. Start a new conversation and try a prompt. + +![Start a Conversation](./images/laminar-openhands-conversation.png) + +Your conversations will now automatically send a trace to Laminar. + +![Laminar Trace](./images/laminar-trace.png) + + + +## Next Steps + + + + Get the most out of your AI coding agents with effective prompting techniques. + + + Reach out to the OpenHands team for deployment assistance or questions. + + + Explore the full OpenHands documentation for usage guides and features. + + + ### Enterprise vs. Open Source Source: https://docs.openhands.dev/enterprise/enterprise-vs-oss.md -This page describes the key differences between **OpenHands Local GUI** (open source) for individual developers and small teams running the Local GUI on their own machines, and **OpenHands Enterprise** for organizations that need advanced collaboration, integrations, and management capabilities. +This page describes the key differences between **OpenHands Agent Canvas** (open source) for individual developers and small teams running the Agent Canvas on their own machines, and **OpenHands Enterprise** for organizations that need advanced collaboration, integrations, and management capabilities. ## Feature Comparison -The table below highlights the key differences between the OpenHands Local GUI and OpenHands Enterprise offerings: +The table below highlights the key differences between the OpenHands Agent Canvas and OpenHands Enterprise offerings: -| Feature | Local GUI | OpenHands Enterprise | +| Feature | Agent Canvas | OpenHands Enterprise | |---------|-------------------|----------------------| | **Full breadth of agent functionality (sub-agents, MCP, skills, model agnosticism)** | ✅ | ✅ | -| **Where does the agent run?** | Local dev machines | Scalable, runtime sandboxes | -| **Scalability** *Run multiple concurrent agent conversations* | Limited by machine | Unlimited, on-demand | -| **'@OpenHands' in Slack and Jira** *Important for real-time resolution of bugs and feedback* | ❌ | ✅ | -| **'@OpenHands' in GitHub, GitLab, Bitbucket** *Important for real-time resolution of PR comments and failing tests* | ❌ | ✅ | -| **Multiple agent conversations in one place** *Give users visibility into all agent conversations* | ✅ | ✅ | -| **Share conversations** *Unlock collaboration use cases* | ❌ | ✅ | -| **Remote monitoring of agent conversations** *Enable Human-in-the-Loop operations for running agents* | ❌ Requires access to machine where agent is running | ✅ Monitor remotely from OpenHands Enterprise UI | -| **Multi-user management and RBAC** *Roll out to several users and teams* | ❌ | ✅ | -| **Automations** *Create scheduled and event-based workflows* | ❌ | ✅ | +| **Where does the agent run?** | Locally or on a custom backend | Scalable, Kubernetes runtimes | +| **Automations**
*Create scheduled and event-based workflows* | ✅ | ✅ | +| **'@OpenHands' in Slack and Jira**
*Important for real-time resolution of bugs and feedback* | Requires custom [Automation](/openhands/usage/automations/overview) | Native integration | +| **'@OpenHands' in GitHub, GitLab, Bitbucket**
*Important for real-time resolution of PR comments and failing tests* | Requires custom [Automation](/openhands/usage/automations/overview) | Native integration | +| **Share conversations**
*Unlock collaboration use cases* | ❌ | ✅ | +| **Multi-user Organizations and RBAC**
*Roll out to several users and teams* | ❌ | ✅ | +| **User and Organization Budgets**
*Monitor and control costs* | ❌ | ✅ | +| **Agent Observability Integrations**
*Centralized logging of conversations* | ❌ | ✅ Uses Laminar| +| **Private Plugin Marketplace**
*Publish reusable plugins for teams to use* | ❌ | ✅ | | **SAML** | ❌ | ✅ | | **REST APIs** | ❌ | ✅ | ## When to Choose Each Option -### OpenHands Local GUI +### OpenHands Agent Canvas -The OpenHands Local GUI is ideal for: +The OpenHands Agent Canvas is ideal for: - Individual developers exploring AI-assisted coding - Small teams with basic requirements - Self-hosted environments where you manage your own infrastructure -- Running OpenHands locally on your own machine +- Running OpenHands locally on your own machine using the Agent Canvas ### OpenHands Enterprise OpenHands Enterprise is the right choice when you need: -- **Team collaboration** — Share conversations and manage multiple users from a single platform +- **Multi-use RBAC** — Manage multiple users from a single platform - **Platform integrations** — Invoke OpenHands directly from Slack, Jira, GitHub, GitLab, or Bitbucket - **Scalability** — Run unlimited parallel agent conversations without local resource constraints - **Enterprise security** — SAML authentication, RBAC, and centralized audit logs -- **Remote monitoring** — Track agent progress in real-time from anywhere +- **Usage Monitoring** — Track and enforce budgets; monitor usage across all users ## Getting Started - Get started with OpenHands on your local machine using Docker or the CLI launcher. + Install Agent Canvas from npm and run OpenHands from your terminal. +### External PostgreSQL +Source: https://docs.openhands.dev/enterprise/external-postgres.md + +OpenHands Enterprise can connect to an external PostgreSQL instance instead of using +the bundled database. This is useful when you have existing database infrastructure, +need specific backup/recovery procedures, or require high availability configurations. + +## PostgreSQL Version + +OpenHands Enterprise requires **PostgreSQL 16.4.0 or above**. PostgreSQL 17 is also supported. + +## Required Databases + +OpenHands Enterprise uses the following databases: + +| Database | Purpose | +|----------|---------| +| `openhands` | Core application data | +| `bitnami_keycloak` | Identity and access management | +| `litellm` | LLM proxy configuration and usage tracking | +| `runtime_api_db` | Runtime/sandbox management | +| `automations` | Scheduled tasks and automation workflows | + +## Database User Requirements + +The PostgreSQL user provided to OpenHands Enterprise needs specific privileges depending +on your preferred setup approach. + +### Option 1: Automatic Database Creation (Recommended) + +If you provide a database user with the `CREATEDB` privilege, OpenHands Enterprise will +automatically create all required databases during installation. + +```sql +-- Create user with CREATEDB privilege +CREATE USER openhands_user WITH PASSWORD 'your-secure-password' CREATEDB; +``` + +When the user creates its own databases, it will automatically have all necessary privileges +on them including the ability to manage the `public` schema. + +### Option 2: Manual Database Creation + +If your security policies prevent granting `CREATEDB`, you must manually create all +databases before installation: + +```sql +-- Create the databases +CREATE DATABASE openhands; +CREATE DATABASE bitnami_keycloak; +CREATE DATABASE litellm; +CREATE DATABASE runtime_api_db; +CREATE DATABASE automations; + +-- Create user without CREATEDB +CREATE USER openhands_user WITH PASSWORD 'your-secure-password'; + +-- Grant privileges on each database +GRANT ALL PRIVILEGES ON DATABASE openhands TO openhands_user; +GRANT ALL PRIVILEGES ON DATABASE bitnami_keycloak TO openhands_user; +GRANT ALL PRIVILEGES ON DATABASE litellm TO openhands_user; +GRANT ALL PRIVILEGES ON DATABASE runtime_api_db TO openhands_user; +GRANT ALL PRIVILEGES ON DATABASE automations TO openhands_user; + +-- Connect to each database and grant schema privileges +\c openhands +GRANT USAGE, CREATE ON SCHEMA public TO openhands_user; + +\c bitnami_keycloak +GRANT USAGE, CREATE ON SCHEMA public TO openhands_user; + +\c litellm +GRANT USAGE, CREATE ON SCHEMA public TO openhands_user; + +\c runtime_api_db +GRANT USAGE, CREATE ON SCHEMA public TO openhands_user; + +\c automations +GRANT USAGE, CREATE ON SCHEMA public TO openhands_user; +``` + +## Network Requirements + +Ensure your PostgreSQL instance is accessible from: + +- The OpenHands application pods/services +- The Keycloak service +- The LiteLLM proxy service +- The Runtime API service + +If using network policies or firewalls, allow connections on the PostgreSQL port (default: 5432) +from the OpenHands deployment. + +## Configuration + +When configuring OpenHands Enterprise, provide your external PostgreSQL connection details +in the Admin Console or Helm values: + +- **Host**: Your PostgreSQL server hostname or IP +- **Port**: PostgreSQL port (default: 5432) +- **Username**: The database user created above +- **Password**: The user's password + + + For production deployments, we recommend enabling SSL/TLS for database connections. + + ### Kubernetes Installation Source: https://docs.openhands.dev/enterprise/k8s-install.md @@ -38755,6 +40005,10 @@ OpenHands Enterprise consists of several components deployed as Kubernetes workl ## Guides + + Configure OpenHands to use your own PostgreSQL database instead of the bundled instance. + + Configure memory, CPU, and storage for optimal performance. @@ -39191,6 +40445,7 @@ All items below must be completed before running the installer: - Inbound ports are open: `80`, `443`, and `30000` - Outbound domains are reachable from the VM - GitHub App prerequisites are prepared +- (Optional) [External PostgreSQL](/enterprise/external-postgres) instance provisioned if using your own database Do not run the installer until preflight checks pass. @@ -39373,6 +40628,13 @@ You should now see the application configuration page. Enter your Anthropic API key from the [Anthropic Console](https://console.anthropic.com/). +### Database Configuration + +By default, OpenHands Enterprise uses a bundled PostgreSQL database. If you need to use your +own PostgreSQL instance (for example, to integrate with existing database infrastructure or +meet specific backup/HA requirements), see [External PostgreSQL](/enterprise/external-postgres) +for setup instructions. + ### GitHub Authentication Enable GitHub Authentication in the Admin Console, then follow these steps to create and diff --git a/llms.txt b/llms.txt index 1a94acc61..2f402f41a 100644 --- a/llms.txt +++ b/llms.txt @@ -107,19 +107,24 @@ from the OpenHands Software Agent SDK. ## OpenHands Web App Server - [About OpenHands](https://docs.openhands.dev/openhands/usage/about.md) +- [Agent Canvas Overview](https://docs.openhands.dev/openhands/usage/agent-canvas/overview.md): Run OpenHands through the Agent Canvas UI and connect it to local or remote backends. - [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 -- [Automations Overview](https://docs.openhands.dev/openhands/usage/automations/overview.md): Create scheduled tasks that run automatically in OpenHands Cloud and Enterprise. +- [Automations](https://docs.openhands.dev/openhands/usage/agent-canvas/automations.md): Use Agent Canvas with the OpenHands automation backend for scheduled and event-driven work. +- [Automations Overview](https://docs.openhands.dev/openhands/usage/automations/overview.md): Create scheduled tasks that run automatically in OpenHands. - [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) - [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. +- [Connect and Manage Backends](https://docs.openhands.dev/openhands/usage/agent-canvas/backends.md): Use Agent Canvas with local, remote, or cloud-backed OpenHands backends. +- [Contribute / Development](https://docs.openhands.dev/openhands/usage/agent-canvas/development.md): Clone Agent Canvas, run it from source, and use the developer workflows. - [Creating Automations](https://docs.openhands.dev/openhands/usage/automations/creating-automations.md): Learn how to create scheduled automations using the Automation Skill. - [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): Configure skills, MCP servers, and backend-synced settings in Agent Canvas. - [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. @@ -134,8 +139,9 @@ from the OpenHands Software Agent SDK. - [Incident Triage](https://docs.openhands.dev/openhands/usage/use-cases/incident-triage.md): Using OpenHands to investigate and resolve production incidents - [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. As well as some additional LLM settings. +- [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 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. @@ -156,8 +162,11 @@ from the OpenHands Software Agent SDK. - [Runtime Architecture](https://docs.openhands.dev/openhands/usage/architecture/runtime.md) - [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. +- [Self-Hosting Agent Canvas](https://docs.openhands.dev/openhands/usage/agent-canvas/self-hosting.md): Run Agent Canvas on your own machine or VM and secure it before exposing it to a network. +- [Setup](https://docs.openhands.dev/openhands/usage/agent-canvas/setup.md): Install Agent Canvas from npm and run it from your terminal. - [Setup](https://docs.openhands.dev/openhands/usage/run-openhands/local-setup.md): Getting started with running OpenHands on your own. - [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 @@ -176,8 +185,12 @@ from the OpenHands Software Agent SDK. - [Jira Cloud Integration](https://docs.openhands.dev/openhands/usage/cloud/project-management/jira-integration.md): Complete guide for setting up Jira Cloud integration with OpenHands Cloud, including service account creation, API token generation, webhook configuration, and workspace integration setup. - [Jira Data Center Integration (Coming soon...)](https://docs.openhands.dev/openhands/usage/cloud/project-management/jira-dc-integration.md): Complete guide for setting up Jira Data Center integration with OpenHands Cloud, including service account creation, personal access token generation, webhook configuration, and workspace integration setup. - [Linear Integration (Coming soon...)](https://docs.openhands.dev/openhands/usage/cloud/project-management/linear-integration.md): Complete guide for setting up Linear integration with OpenHands Cloud, including service account creation, API key generation, webhook configuration, and workspace integration setup. +- [Managing Members](https://docs.openhands.dev/openhands/usage/cloud/organizations/managing-members.md): How to invite users and manage team members in your organization. +- [Organization Settings](https://docs.openhands.dev/openhands/usage/cloud/organizations/settings.md): Configure shared resources and settings for your OpenHands organization. +- [Organizations Overview](https://docs.openhands.dev/openhands/usage/cloud/organizations/overview.md): Manage teams and collaborate with shared resources in OpenHands Cloud or OpenHands Enterprise. - [Plugin Launcher](https://docs.openhands.dev/openhands/usage/cloud/plugin-launcher.md): Use the OpenHands Cloud `/launch` route to open a conversation with plugins or skills pre-configured from a Git repository. - [Project Management Tool Integrations (Coming soon...)](https://docs.openhands.dev/openhands/usage/cloud/project-management/overview.md): Overview of OpenHands Cloud integrations with project management platforms including Jira Cloud, Jira Data Center, and Linear. Learn about setup requirements, usage methods, and troubleshooting. +- [Roles and Permissions](https://docs.openhands.dev/openhands/usage/cloud/organizations/roles-permissions.md): Understanding the different permission levels in OpenHands Organizations. - [Slack Integration](https://docs.openhands.dev/openhands/usage/cloud/slack-installation.md): This guide walks you through installing the OpenHands Slack app. ## OpenHands Overview @@ -197,7 +210,9 @@ from the OpenHands Software Agent SDK. ## Other +- [Analytics](https://docs.openhands.dev/enterprise/analytics.md): Get started with LLM observability and tracing in OpenHands Enterprise. - [Enterprise vs. Open Source](https://docs.openhands.dev/enterprise/enterprise-vs-oss.md): Compare OpenHands Enterprise and Open Source offerings to choose the right option for your team +- [External PostgreSQL](https://docs.openhands.dev/enterprise/external-postgres.md): Configure OpenHands Enterprise to use your own PostgreSQL database - [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 - [Quick Start](https://docs.openhands.dev/enterprise/quick-start.md): Get started with a 30-day trial of OpenHands Enterprise. diff --git a/openhands/usage/advanced/custom-sandbox-guide.mdx b/openhands/usage/advanced/custom-sandbox-guide.mdx index 2aea822b2..9eac3de4c 100644 --- a/openhands/usage/advanced/custom-sandbox-guide.mdx +++ b/openhands/usage/advanced/custom-sandbox-guide.mdx @@ -5,7 +5,7 @@ description: This guide is for users that would like to use their own custom Doc --- - These settings are only available in [Local GUI](/openhands/usage/run-openhands/local-setup). OpenHands Cloud uses managed sandbox environments. + These settings are only available in [Local GUI (Legacy)](/openhands/usage/run-openhands/local-setup). OpenHands Cloud uses managed sandbox environments. The sandbox is where the agent performs its tasks. Instead of running commands directly on your computer diff --git a/openhands/usage/agent-canvas/automations.mdx b/openhands/usage/agent-canvas/automations.mdx new file mode 100644 index 000000000..2f56abc60 --- /dev/null +++ b/openhands/usage/agent-canvas/automations.mdx @@ -0,0 +1,42 @@ +--- +title: Automations +description: Use Agent Canvas with the OpenHands automation backend for scheduled and event-driven work. +--- + +Agent Canvas can work with the OpenHands automation backend so you can run agents on a schedule or in response to external events. + +## What You Can Do + +In the `Automations` view, you can: + +- browse existing automations +- inspect automation configuration and activity +- enable or disable automations +- work with recommended automation flows + +## Local Stack Behavior + +When you start Agent Canvas with the `agent-canvas` command, the local stack includes the automation backend by default. + +That makes the built-in local setup a good starting point for: + +- scheduled maintenance tasks +- event-driven coding workflows +- testing automation ideas before deploying them elsewhere + +## Backend Availability Matters + +The `Automations` view depends on the active backend. + +- If the active backend has a healthy automation service, Agent Canvas can load and manage automations. +- If it does not, Agent Canvas shows a backend-not-configured or unavailable state. + + + Some automation editing flows are currently focused on local backends first, while the broader hosted experience continues to evolve. + + +## Related Guides + +- [Connect and Manage Backends](/openhands/usage/agent-canvas/backends) +- [Self-Hosting Agent Canvas](/openhands/usage/agent-canvas/self-hosting) +- [Automations Overview](/openhands/usage/automations/overview) diff --git a/openhands/usage/agent-canvas/backends.mdx b/openhands/usage/agent-canvas/backends.mdx new file mode 100644 index 000000000..b80cd6301 --- /dev/null +++ b/openhands/usage/agent-canvas/backends.mdx @@ -0,0 +1,63 @@ +--- +title: Connect and Manage Backends +description: Use Agent Canvas with local, remote, or cloud-backed OpenHands backends. +--- + +Agent Canvas always works against an **active backend**. Conversations, backend-synced settings, and some feature availability depend on which backend is currently selected. + +## Default Local Backend + +On first launch, Agent Canvas seeds a default local backend that points to the stack started by the `agent-canvas` command. + +That default backend is a good fit when you want to: + +- Run OpenHands entirely on your current machine +- Test configuration changes quickly +- Use the bundled automation backend locally + +## Managing Additional Backends + +Use the backend switcher in the UI to open `Manage Backends`, then add or edit backend entries. + +Each backend entry includes: + +- A display name +- A host or base URL +- An API key when the backend requires one +- A backend kind such as local or cloud + +## Local vs. Cloud Backends + +| Backend Type | Typical Use | +|--------------|-------------| +| **Local** | A machine you control directly, such as your laptop, a VM, or a team-managed host | +| **Cloud** | A backend exposed through OpenHands Cloud services when available | + +## What Changes When You Switch Backends + +Switching the active backend changes more than just where conversations run. + +- `Settings` read and write against the active backend +- LLM availability depends on what that backend exposes +- `Customize > MCP Servers` acts on the active backend's MCP configuration +- Automations depend on whether the active backend has the automation service available + + + If a backend is unreachable, Agent Canvas can still open the backend management flow so you can fix the host, API key, or selection without leaving the app. + + +## Recommended Setup Pattern + +A common setup is to keep one local backend for experimentation and add one or more remote backends for longer-running or more powerful workloads. + +Examples: + +- A laptop backend for quick local tasks +- A dedicated VM backend for always-on work +- A cloud backend for hosted conversations + +## Related Guides + +- [Setup](/openhands/usage/agent-canvas/setup) +- [Customize and Settings](/openhands/usage/agent-canvas/customize-and-settings) +- [Self-Hosting Agent Canvas](/openhands/usage/agent-canvas/self-hosting) diff --git a/openhands/usage/agent-canvas/customize-and-settings.mdx b/openhands/usage/agent-canvas/customize-and-settings.mdx new file mode 100644 index 000000000..9a617e42a --- /dev/null +++ b/openhands/usage/agent-canvas/customize-and-settings.mdx @@ -0,0 +1,56 @@ +--- +title: Customize and Settings +description: Configure skills, MCP servers, and backend-synced settings in Agent Canvas. +--- + +Agent Canvas separates **Customize** from **Settings**. + +- `Customize` is where you extend what the agent can use. +- `Settings` is where you configure backend-synced behavior for the active backend. + +## Customize + +Open the top-level `Customize` area to manage: + +- `Skills` +- `MCP Servers` + + + 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 and verification-related behavior | +| `Application` | UI-level preferences and app behavior | +| `Secrets` | Stored secrets used by the active backend | + +## Backend-Synced Behavior + +Each settings section is synced with the **active backend**. That means: + +- changing backends changes which settings you are editing +- a setting saved for one backend does 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) +- [LLM Profiles and Model Configuration](/openhands/usage/agent-canvas/llm-profiles) +- [Automations](/openhands/usage/agent-canvas/automations) diff --git a/openhands/usage/agent-canvas/development.mdx b/openhands/usage/agent-canvas/development.mdx new file mode 100644 index 000000000..27d5e504e --- /dev/null +++ b/openhands/usage/agent-canvas/development.mdx @@ -0,0 +1,81 @@ +--- +title: Contribute / Development +description: Clone Agent Canvas, run it from source, and use the developer workflows. +--- + +This page is for contributors and advanced users who want to run Agent Canvas from a local checkout. If you only want to use Agent Canvas, follow the [Setup](/openhands/usage/agent-canvas/setup) guide instead. + +## Clone the Repository + +```bash +git clone https://github.com/OpenHands/agent-canvas.git +cd agent-canvas +npm install +``` + +## Recommended Local Workflow + +The standard development flow runs the full local stack with live frontend updates: + +```bash +npm run dev +``` + +That workflow starts: + +- the Agent Canvas frontend +- the OpenHands agent server +- the automation backend +- the ingress proxy that ties them together + +## Other Useful Development Modes + +| Command | When to Use It | +|---------|----------------| +| `npm run dev` | Full local development stack | +| `npm run dev:static` | Serve a production-style static frontend during development | +| `npm run dev:minimal` | Run without the automation backend | +| `npm run dev:frontend` | Point the frontend at a separately managed backend | +| `npm run dev:mock` | Work on the UI without a live backend | + +## Verification Commands + +Use the repo's built-in checks before sending a change upstream: + +```bash +npm run test +npm run build +``` + +## Development Environment Variables + +These variables are mainly useful when you are running Agent Canvas from a local checkout. + +| Variable | Purpose | +|----------|---------| +| `VITE_BACKEND_BASE_URL` | Base URL used by browser-side requests | +| `VITE_BACKEND_HOST` | Backend target for the Vite dev proxy | +| `VITE_SESSION_API_KEY` | Session API key to send when the backend requires one | +| `VITE_WORKING_DIR` | Workspace path used for new conversations | +| `VITE_WORKER_URLS` | Optional worker URLs for Browser integrations | +| `VITE_ENABLE_BROWSER_TOOLS` | Disable browser tools for new conversations when set to `false` | +| `VITE_LOAD_PUBLIC_SKILLS` | Disable loading public skills when set to `false` | +| `VITE_FRONTEND_PORT` | Frontend dev server port | +| `VITE_USE_TLS` | Use HTTPS or WSS for the dev proxy | +| `VITE_INSECURE_SKIP_VERIFY` | Skip TLS verification for proxied backend requests | +| `VITE_MOCK_API` | Enable mock API responses | + +## Advanced Source Overrides + +The development stack also supports source and version overrides for the agent server: + +- `OH_AGENT_SERVER_LOCAL_PATH` +- `OH_AGENT_SERVER_GIT_REF` +- `OH_AGENT_SERVER_VERSION` + +These are useful when you are developing Agent Canvas alongside a local `software-agent-sdk` checkout. + +## Learn More + +- [Agent Canvas Repository](https://github.com/OpenHands/agent-canvas) +- [Self-Hosting Agent Canvas](/openhands/usage/agent-canvas/self-hosting) diff --git a/openhands/usage/agent-canvas/llm-profiles.mdx b/openhands/usage/agent-canvas/llm-profiles.mdx new file mode 100644 index 000000000..d5665111f --- /dev/null +++ b/openhands/usage/agent-canvas/llm-profiles.mdx @@ -0,0 +1,49 @@ +--- +title: LLM Profiles and Model Configuration +description: Configure models in Agent Canvas and use saved LLM profiles during conversations. +--- + +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) diff --git a/openhands/usage/agent-canvas/overview.mdx b/openhands/usage/agent-canvas/overview.mdx new file mode 100644 index 000000000..81ee582df --- /dev/null +++ b/openhands/usage/agent-canvas/overview.mdx @@ -0,0 +1,45 @@ +--- +title: Agent Canvas Overview +description: Run OpenHands through the Agent Canvas UI and connect it to local or remote backends. +--- + +The **Agent Canvas** is the Beta UI for running OpenHands from your own machine or against backends you manage. It gives you one place to start conversations, switch backends, configure models, manage MCP servers, and work with automations. + + + Agent Canvas is in Beta. Expect the install path, packaging, and some UI details to keep evolving. + + +## What Agent Canvas Includes + +When you run `agent-canvas`, you get a complete local stack: + +- The Agent Canvas web UI +- An OpenHands agent server +- The automation backend used for scheduled and event-driven workflows +- A local ingress endpoint that serves the UI and routes API traffic + +## Key Concepts + +| Concept | What It Means | +|---------|----------------| +| **Agent Canvas UI** | The browser interface for conversations, customization, settings, and automations | +| **Active Backend** | The backend Agent Canvas is currently using for conversations and synced settings | +| **Local Backend** | A backend running on your own machine or another machine you control | +| **Cloud Backend** | A backend backed by OpenHands Cloud services when available | +| **Customize** | The top-level area for `Skills` and `MCP Servers` | +| **Settings** | Backend-synced configuration for `Agent`, `LLM`, `Condenser`, `Verification`, `Application`, and `Secrets` | + +## How It Fits with Other OpenHands Products + +- **Agent Canvas** is the recommended local and self-hosted UI path. +- **Local GUI (Legacy)** remains documented for older Docker-based workflows. +- **OpenHands Cloud** is the hosted product. +- **OpenHands SDK** is the Python framework behind the agent system. + +## Where to Start + +- [Setup](/openhands/usage/agent-canvas/setup) — Install Agent Canvas globally from npm and run it 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. +- [Automations](/openhands/usage/agent-canvas/automations) — Work with the bundled automation backend. +- [Self-Hosting Agent Canvas](/openhands/usage/agent-canvas/self-hosting) — Run Agent Canvas on a VM or other dedicated machine. diff --git a/openhands/usage/agent-canvas/self-hosting.mdx b/openhands/usage/agent-canvas/self-hosting.mdx new file mode 100644 index 000000000..fd59f69d4 --- /dev/null +++ b/openhands/usage/agent-canvas/self-hosting.mdx @@ -0,0 +1,75 @@ +--- +title: Self-Hosting Agent Canvas +description: Run Agent Canvas on your own machine or VM and secure it before exposing it to a network. +--- + +Self-hosting Agent Canvas lets you keep the UI, agent server, and automation backend on infrastructure you control. + + + Anyone who can reach your Agent Canvas deployment can potentially drive an agent that reads files, runs shell commands, and accesses the network. Lock down the host before exposing it to anyone else. + + +## Common Self-Hosted Patterns + +Teams usually self-host Agent Canvas in one of these ways: + +- on a dedicated developer workstation +- on a VM in a cloud provider +- on a machine inside a private network or VPN + +## Recommended Security Checklist + +Before you expose Agent Canvas to a broader network, make sure you: + +1. Restrict inbound network access. +2. Use TLS and an authenticated reverse proxy if the UI is reachable over the internet. +3. Treat the host as sensitive infrastructure because it stores secrets, conversations, and working copies. +4. Keep the machine patched and limit who can access it. + +## Basic VM Workflow + +1. Provision a Linux or macOS machine you control. +2. Install Node.js, npm, and `uv`. +3. Install Agent Canvas globally: + +```bash +npm install -g @openhands/agent-canvas +``` + +4. Start Agent Canvas: + +```bash +agent-canvas +``` + +5. Put a reverse proxy such as nginx in front of it if you need browser access beyond localhost. + +## Reverse Proxy and Auth + +If you publish Agent Canvas behind a domain: + +- terminate TLS at the reverse proxy +- require authentication before requests reach Agent Canvas +- keep the backing services off the public network whenever possible + +## Connecting from Another Machine + +You do not need to run the UI and the backend on the same computer. + +A common pattern is: + +- run Agent Canvas on a dedicated host or VM +- open the UI there directly, or through a secure reverse proxy +- or connect a local Agent Canvas instance to that remote backend through `Manage Backends` + +## Detailed Hardening Reference + +For a longer VM hardening walkthrough, see the repository guide: + +- [SELF_HOSTING.md](https://github.com/OpenHands/agent-canvas/blob/main/SELF_HOSTING.md) + +## Related Guides + +- [Setup](/openhands/usage/agent-canvas/setup) +- [Connect and Manage Backends](/openhands/usage/agent-canvas/backends) +- [Troubleshooting](/openhands/usage/agent-canvas/troubleshooting) diff --git a/openhands/usage/agent-canvas/setup.mdx b/openhands/usage/agent-canvas/setup.mdx new file mode 100644 index 000000000..4473f0f4b --- /dev/null +++ b/openhands/usage/agent-canvas/setup.mdx @@ -0,0 +1,85 @@ +--- +title: Setup +description: Install Agent Canvas from npm and run it from your terminal. +--- + +This page documents the recommended install path for Agent Canvas: install the published package globally with npm, then start it with the `agent-canvas` command. + +## Prerequisites + +Before you start, make sure the machine has: + +- Node.js 22.12 or later +- `npm` +- [`uv`](https://docs.astral.sh/uv/getting-started/installation/) + + + Agent Canvas starts an agent server on the machine where you run it. Treat that machine as trusted infrastructure and review the guidance in [Self-Hosting Agent Canvas](/openhands/usage/agent-canvas/self-hosting) before exposing it to a network you do not control. + + +## Install Agent Canvas + +```bash +npm install -g @openhands/agent-canvas +``` + +## Start Agent Canvas + +```bash +agent-canvas +``` + +By default, Agent Canvas starts on `http://localhost:8000`. + +## Change the Port + +Use the public `--port` flag when you need a different ingress port: + +```bash +agent-canvas --port 3000 +``` + +## CLI Flags + +The installed `agent-canvas` binary currently exposes the following public flags: + +| Flag | Description | +|------|-------------| +| `-p`, `--port ` | Set the ingress port for the local Agent Canvas stack | +| `-h`, `--help` | Show the built-in help output | + +## Runtime Environment Variables + +Agent Canvas keeps most day-to-day configuration in the UI, not in environment variables. The current runtime-level overrides are: + +| Variable | Purpose | +|----------|---------| +| `OH_SECRET_KEY` | Secret used to protect stored settings and secrets | +| `OH_AGENT_SERVER_GIT_REF` | Advanced override for running the agent server from a specific git ref | +| `OH_AGENT_SERVER_VERSION` | Advanced override for pinning a specific agent server version | +| `OH_AGENT_SERVER_LOCAL_PATH` | Development-only override for using a local `software-agent-sdk` checkout | + + + 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. Start a conversation from the `Code` view. + +## Docker Image Placeholder + + + A published Agent Canvas Docker image is coming soon. This section is intentionally reserved so the docs can add a container-based install path without changing the overall navigation. + + +## 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) diff --git a/openhands/usage/agent-canvas/troubleshooting.mdx b/openhands/usage/agent-canvas/troubleshooting.mdx new file mode 100644 index 000000000..a55d9cc49 --- /dev/null +++ b/openhands/usage/agent-canvas/troubleshooting.mdx @@ -0,0 +1,65 @@ +--- +title: Troubleshooting +description: Common Agent Canvas setup and runtime issues, plus places to ask for help. +--- + +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) diff --git a/openhands/usage/cli/gui-server.mdx b/openhands/usage/cli/gui-server.mdx index adaaebdf8..979814781 100644 --- a/openhands/usage/cli/gui-server.mdx +++ b/openhands/usage/cli/gui-server.mdx @@ -133,6 +133,6 @@ If port 3000 is already in use, stop the conflicting service or use a different ## See Also -- [Local GUI Setup](/openhands/usage/run-openhands/local-setup) - Detailed GUI setup guide +- [Local GUI (Legacy) Setup](/openhands/usage/run-openhands/local-setup) - Detailed legacy GUI setup guide - [Web Interface](/openhands/usage/cli/web-interface) - Lightweight browser access - [Docker Sandbox](/openhands/usage/sandboxes/docker) - Docker sandbox configuration details diff --git a/openhands/usage/run-openhands/gui-mode.mdx b/openhands/usage/run-openhands/gui-mode.mdx index 0eef5a0c6..2605655d7 100644 --- a/openhands/usage/run-openhands/gui-mode.mdx +++ b/openhands/usage/run-openhands/gui-mode.mdx @@ -3,6 +3,11 @@ title: Configure description: High level overview of configuring the OpenHands Web interface. --- + + This page documents **Local GUI (Legacy)**. For the current local and self-hosted experience, see [Agent Canvas (Beta)](/openhands/usage/agent-canvas/setup). + + + ## Prerequisites - [OpenHands is running](/openhands/usage/run-openhands/local-setup) diff --git a/openhands/usage/run-openhands/local-setup.mdx b/openhands/usage/run-openhands/local-setup.mdx index d2342e91f..244887ed4 100644 --- a/openhands/usage/run-openhands/local-setup.mdx +++ b/openhands/usage/run-openhands/local-setup.mdx @@ -3,6 +3,11 @@ title: Setup description: Getting started with running OpenHands on your own. --- + + This page documents **Local GUI (Legacy)**. For the current local and self-hosted experience, see [Agent Canvas (Beta)](/openhands/usage/agent-canvas/setup). + + + ## Recommended Methods for Running OpenHands on Your Local System ### System Requirements diff --git a/openhands/usage/settings/integrations-settings.mdx b/openhands/usage/settings/integrations-settings.mdx index 774148c24..28fd75d77 100644 --- a/openhands/usage/settings/integrations-settings.mdx +++ b/openhands/usage/settings/integrations-settings.mdx @@ -29,7 +29,7 @@ you're using [OpenHands Cloud](/openhands/usage/cloud/openhands-cloud) or ## Running on Your Own Integrations Settings - These settings are only available in [OpenHands Local GUI](/openhands/usage/run-openhands/local-setup). + These settings are only available in [OpenHands Local GUI (Legacy)](/openhands/usage/run-openhands/local-setup). ### Version Control Integrations diff --git a/openhands/usage/v0/advanced/V0_configuration-options.mdx b/openhands/usage/v0/advanced/V0_configuration-options.mdx index 3a1eedcb5..a435acf3d 100644 --- a/openhands/usage/v0/advanced/V0_configuration-options.mdx +++ b/openhands/usage/v0/advanced/V0_configuration-options.mdx @@ -10,7 +10,7 @@ description: This page outlines all available configuration options for OpenHand - These settings are only available in [Local GUI](/openhands/usage/run-openhands/local-setup). OpenHands Cloud uses a web-based settings interface. + These settings are only available in [Local GUI (Legacy)](/openhands/usage/run-openhands/local-setup). OpenHands Cloud uses a web-based settings interface. diff --git a/openhands/usage/v0/runtimes/V0_overview.mdx b/openhands/usage/v0/runtimes/V0_overview.mdx index 49ed08c39..ff7ff9361 100644 --- a/openhands/usage/v0/runtimes/V0_overview.mdx +++ b/openhands/usage/v0/runtimes/V0_overview.mdx @@ -9,7 +9,7 @@ description: This section is for users that would like to use a runtime other th - These settings are only available in [Local GUI](/openhands/usage/run-openhands/local-setup). OpenHands Cloud uses managed sandbox environments. + These settings are only available in [Local GUI (Legacy)](/openhands/usage/run-openhands/local-setup). OpenHands Cloud uses managed sandbox environments. A Runtime is an environment where the OpenHands agent can edit files and run diff --git a/overview/introduction.mdx b/overview/introduction.mdx index 9f510db48..be99a1b96 100644 --- a/overview/introduction.mdx +++ b/overview/introduction.mdx @@ -20,11 +20,10 @@ with e.g. Claude Code or Codex. You can power it with Claude, GPT, or any other [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 -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. +## OpenHands Agent Canvas +Use Agent Canvas for the current local and self-hosted OpenHands UI. It runs from your terminal, connects to local or remote backends, and includes views for conversations, customization, settings, and automations. -[Check out the docs](https://docs.openhands.dev/openhands/usage/run-openhands/local-setup) or view the source in this repo. +[Check out the docs](https://docs.openhands.dev/openhands/usage/agent-canvas/setup) or [view the source](https://github.com/OpenHands/agent-canvas). ## OpenHands Cloud This is a commercial deployment of OpenHands GUI, running on hosted infrastructure. diff --git a/overview/model-context-protocol.mdx b/overview/model-context-protocol.mdx index eaebd4443..c87342091 100644 --- a/overview/model-context-protocol.mdx +++ b/overview/model-context-protocol.mdx @@ -20,7 +20,7 @@ When OpenHands starts, it: |----------|---------------|---------------------|---------------| | **CLI** | ✅ Full Support | `~/.openhands/mcp.json` file | [CLI MCP Servers](/openhands/usage/cli/mcp-servers) | | **SDK** | ✅ Full Support | Programmatic configuration | [SDK MCP Guide](/sdk/guides/mcp) | -| **Local GUI** | ✅ Full Support | Settings UI + config files | [Local GUI](/openhands/usage/run-openhands/local-setup) | +| **Agent Canvas** | ✅ Full Support | `Customize > MCP Servers` | [Customize and Settings](/openhands/usage/agent-canvas/customize-and-settings) | | **OpenHands Cloud** | ✅ Full Support | Cloud UI settings | [Cloud GUI](/openhands/usage/cloud/cloud-ui) | ## Platform-Specific Differences @@ -38,11 +38,11 @@ When OpenHands starts, it: - Dynamic server registration and management - Integration with custom tool systems
- - - Visual configuration through Settings UI - - File-based configuration backup + + - Visual configuration through `Customize > MCP Servers` - Real-time server status display - Supports all transport protocols + - Synced to the active backend - Cloud-based configuration management @@ -54,7 +54,7 @@ When OpenHands starts, it: ## Getting Started with MCP -- **For detailed configuration**: See [MCP Settings](/openhands/usage/settings/mcp-settings) +- **For detailed configuration**: See [Customize and Settings](/openhands/usage/agent-canvas/customize-and-settings) - **For CLI usage**: See [CLI MCP Servers](/openhands/usage/cli/mcp-servers) - **For SDK integration**: See [SDK MCP Guide](/sdk/guides/mcp) - **For architecture details**: See [MCP Architecture](/sdk/arch/mcp) \ No newline at end of file diff --git a/overview/quickstart.mdx b/overview/quickstart.mdx index 843e997f5..e8871c8ab 100644 --- a/overview/quickstart.mdx +++ b/overview/quickstart.mdx @@ -22,11 +22,11 @@ Get started with OpenHands in minutes. Choose the option that works best for you - Headless mode for CI/CD - Lightweight installation
- - Run OpenHands locally with a web-based interface. Bring your own LLM and API key. + + Install Agent Canvas from npm and run it from your terminal. - - Full control over your environment - - Works offline - - Docker-based setup + - Local and remote backend workflows + - Automations, skills, and MCP support + - Self-hosted friendly diff --git a/overview/skills.mdx b/overview/skills.mdx index b7f266cc3..f85dc66dc 100644 --- a/overview/skills.mdx +++ b/overview/skills.mdx @@ -100,7 +100,7 @@ Each skill file may include frontmatter that provides additional information. In |----------|---------------|---------------------|----------------|---------------| | **CLI** | ✅ Full Support | `~/.agents/skills/` (user-level) and `.agents/skills/` (repo-level) | File-based markdown | [Skills Overview](/overview/skills) | | **SDK** | ✅ Full Support | Programmatic `Skill` objects | Code-based configuration | [SDK Skills Guide](/sdk/guides/skill) | -| **Local GUI** | ✅ Full Support | `.agents/skills/` + UI | File-based with UI management | [Local Setup](/openhands/usage/run-openhands/local-setup) | +| **Agent Canvas** | ✅ Full Support | `.agents/skills/` + UI | File-based with UI management | [Customize and Settings](/openhands/usage/agent-canvas/customize-and-settings) | | **OpenHands Cloud** | ✅ Full Support | Cloud UI + repository integration | Managed skill library | [Cloud UI](/openhands/usage/cloud/cloud-ui) | ## Platform-Specific Differences @@ -120,11 +120,11 @@ Each skill file may include frontmatter that provides additional information. In - Integration with custom workflows - Full control over skill lifecycle - - - Visual skill management through UI - - File-based storage with GUI editing + + - Visual skill management through `Customize` + - File-based storage with UI editing - Real-time skill status display - - Drag-and-drop skill organization + - Backend-aware customization workflows - Cloud-based skill library management From 8edd42bcf42b76a232282f833671289d3c1f60f6 Mon Sep 17 00:00:00 2001 From: Devin Date: Thu, 21 May 2026 19:35:54 -0400 Subject: [PATCH 2/6] Adjust phrasing --- openhands/usage/agent-canvas/automations.mdx | 9 +++++++++ openhands/usage/agent-canvas/backends.mdx | 5 +++-- openhands/usage/agent-canvas/customize-and-settings.mdx | 4 ++++ openhands/usage/agent-canvas/development.mdx | 2 +- openhands/usage/agent-canvas/self-hosting.mdx | 7 +++---- openhands/usage/agent-canvas/setup.mdx | 3 ++- 6 files changed, 22 insertions(+), 8 deletions(-) diff --git a/openhands/usage/agent-canvas/automations.mdx b/openhands/usage/agent-canvas/automations.mdx index 2f56abc60..7413b2c27 100644 --- a/openhands/usage/agent-canvas/automations.mdx +++ b/openhands/usage/agent-canvas/automations.mdx @@ -14,6 +14,15 @@ In the `Automations` view, you can: - 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 + ## Local Stack Behavior When you start Agent Canvas with the `agent-canvas` command, the local stack includes the automation backend by default. diff --git a/openhands/usage/agent-canvas/backends.mdx b/openhands/usage/agent-canvas/backends.mdx index b80cd6301..a04c03415 100644 --- a/openhands/usage/agent-canvas/backends.mdx +++ b/openhands/usage/agent-canvas/backends.mdx @@ -19,12 +19,13 @@ That default backend is a good fit when you want to: Use the backend switcher in the UI to open `Manage Backends`, then add or edit backend entries. -Each backend entry includes: +Each backend entry stores: - A display name - A host or base URL - An API key when the backend requires one -- A backend kind such as local or cloud + +Agent Canvas also tracks whether a backend is local or cloud so it can adjust the available flows. ## Local vs. Cloud Backends diff --git a/openhands/usage/agent-canvas/customize-and-settings.mdx b/openhands/usage/agent-canvas/customize-and-settings.mdx index 9a617e42a..04cb680f2 100644 --- a/openhands/usage/agent-canvas/customize-and-settings.mdx +++ b/openhands/usage/agent-canvas/customize-and-settings.mdx @@ -15,6 +15,8 @@ Open the top-level `Customize` area to manage: - `Skills` - `MCP Servers` +Use the section navigation inside `Customize` to switch between those pages. + MCP configuration lives under `Customize > MCP Servers`, not under `Settings`. @@ -32,6 +34,8 @@ The `Settings` area currently includes the following sections: | `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. + ## Backend-Synced Behavior Each settings section is synced with the **active backend**. That means: diff --git a/openhands/usage/agent-canvas/development.mdx b/openhands/usage/agent-canvas/development.mdx index 27d5e504e..ac1f6f0ed 100644 --- a/openhands/usage/agent-canvas/development.mdx +++ b/openhands/usage/agent-canvas/development.mdx @@ -59,7 +59,7 @@ These variables are mainly useful when you are running Agent Canvas from a local | `VITE_WORKING_DIR` | Workspace path used for new conversations | | `VITE_WORKER_URLS` | Optional worker URLs for Browser integrations | | `VITE_ENABLE_BROWSER_TOOLS` | Disable browser tools for new conversations when set to `false` | -| `VITE_LOAD_PUBLIC_SKILLS` | Disable loading public skills when set to `false` | +| `VITE_LOAD_PUBLIC_SKILLS` | Enable loading public skills when set to `true` | | `VITE_FRONTEND_PORT` | Frontend dev server port | | `VITE_USE_TLS` | Use HTTPS or WSS for the dev proxy | | `VITE_INSECURE_SKIP_VERIFY` | Skip TLS verification for proxied backend requests | diff --git a/openhands/usage/agent-canvas/self-hosting.mdx b/openhands/usage/agent-canvas/self-hosting.mdx index fd59f69d4..7cd1e6307 100644 --- a/openhands/usage/agent-canvas/self-hosting.mdx +++ b/openhands/usage/agent-canvas/self-hosting.mdx @@ -56,11 +56,10 @@ If you publish Agent Canvas behind a domain: You do not need to run the UI and the backend on the same computer. -A common pattern is: +Two common patterns are: -- run Agent Canvas on a dedicated host or VM -- open the UI there directly, or through a secure reverse proxy -- or connect a local Agent Canvas instance to that remote backend through `Manage Backends` +- Run the full Agent Canvas stack on a dedicated host or VM, then open that UI directly or through a secure reverse proxy. +- Keep Agent Canvas on your laptop, and add the remote backend through `Manage Backends`. ## Detailed Hardening Reference diff --git a/openhands/usage/agent-canvas/setup.mdx b/openhands/usage/agent-canvas/setup.mdx index 4473f0f4b..83b36ffd3 100644 --- a/openhands/usage/agent-canvas/setup.mdx +++ b/openhands/usage/agent-canvas/setup.mdx @@ -70,7 +70,8 @@ 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. Start a conversation from the `Code` view. +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. ## Docker Image Placeholder From e87c887579cff29f951a1964503d02e2c108d750 Mon Sep 17 00:00:00 2001 From: Devin Date: Thu, 21 May 2026 19:44:34 -0400 Subject: [PATCH 3/6] Backend is not just Cloud --- openhands/usage/agent-canvas/backends.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openhands/usage/agent-canvas/backends.mdx b/openhands/usage/agent-canvas/backends.mdx index a04c03415..8b9a88d4b 100644 --- a/openhands/usage/agent-canvas/backends.mdx +++ b/openhands/usage/agent-canvas/backends.mdx @@ -32,7 +32,7 @@ Agent Canvas also tracks whether a backend is local or cloud so it can adjust th | Backend Type | Typical Use | |--------------|-------------| | **Local** | A machine you control directly, such as your laptop, a VM, or a team-managed host | -| **Cloud** | A backend exposed through OpenHands Cloud services when available | +| **Cloud** | A compatible backend running an agent-server or OpenHands Cloud | ## What Changes When You Switch Backends From 50ae0e4544ca72a1600d423d738bb7226718344e Mon Sep 17 00:00:00 2001 From: Devin Date: Tue, 26 May 2026 10:49:10 -0400 Subject: [PATCH 4/6] Updates from recent changes to repo --- .../agent-canvas/customize-and-settings.mdx | 1 + openhands/usage/agent-canvas/development.mdx | 29 +++++++++++++++++-- openhands/usage/agent-canvas/overview.mdx | 2 +- openhands/usage/agent-canvas/self-hosting.mdx | 14 +++++---- openhands/usage/agent-canvas/setup.mdx | 2 +- 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/openhands/usage/agent-canvas/customize-and-settings.mdx b/openhands/usage/agent-canvas/customize-and-settings.mdx index 04cb680f2..a5186562a 100644 --- a/openhands/usage/agent-canvas/customize-and-settings.mdx +++ b/openhands/usage/agent-canvas/customize-and-settings.mdx @@ -14,6 +14,7 @@ Open the top-level `Customize` area to manage: - `Skills` - `MCP Servers` +- `Plugins` (currently marked `Coming Soon`) Use the section navigation inside `Customize` to switch between those pages. diff --git a/openhands/usage/agent-canvas/development.mdx b/openhands/usage/agent-canvas/development.mdx index ac1f6f0ed..11b509890 100644 --- a/openhands/usage/agent-canvas/development.mdx +++ b/openhands/usage/agent-canvas/development.mdx @@ -21,6 +21,8 @@ The standard development flow runs the full local stack with live frontend updat npm run dev ``` +That workflow uses `uvx` to start the agent server and automation backend, then fronts them with the Vite dev server and ingress proxy. + That workflow starts: - the Agent Canvas frontend @@ -33,11 +35,16 @@ That workflow starts: | Command | When to Use It | |---------|----------------| | `npm run dev` | Full local development stack | -| `npm run dev:static` | Serve a production-style static frontend during development | -| `npm run dev:minimal` | Run without the automation backend | +| `npm run dev:static` | Serve a static frontend build instead of the Vite dev server | +| `npm run dev:minimal` | Run only the agent server and Vite, without automation or ingress | +| `npm run dev:extra-backend` | Start an additional local backend that shares the main dev stack's persistence | | `npm run dev:frontend` | Point the frontend at a separately managed backend | | `npm run dev:mock` | Work on the UI without a live backend | +`npm run dev:minimal` serves the frontend directly on `http://localhost:3001`. + +`npm run dev:frontend` expects a separately managed backend at `127.0.0.1:8000` unless you override the frontend proxy settings. + ## Verification Commands Use the repo's built-in checks before sending a change upstream: @@ -49,14 +56,28 @@ npm run build ## Development Environment Variables +You can place frontend overrides in a local `.env` file based on `.env.sample`. + These variables are mainly useful when you are running Agent Canvas from a local checkout. +### Launcher Variables + +| Variable | Purpose | +|----------|---------| +| `PORT` | Ingress port for the bundled development stack | +| `OH_AUTOMATION_GIT_REF` | Git ref used for the automation backend | +| `OH_CANVAS_SAFE_BACKEND_PORT` | Backend port for the isolated local agent server | +| `OH_CANVAS_SAFE_VSCODE_PORT` | VS Code sidecar port for the isolated local agent server | +| `OH_CANVAS_SAFE_STATE_DIR` | Base directory for isolated local state | + +### Frontend Variables + | Variable | Purpose | |----------|---------| | `VITE_BACKEND_BASE_URL` | Base URL used by browser-side requests | | `VITE_BACKEND_HOST` | Backend target for the Vite dev proxy | | `VITE_SESSION_API_KEY` | Session API key to send when the backend requires one | -| `VITE_WORKING_DIR` | Workspace path used for new conversations | +| `VITE_WORKING_DIR` | Workspace path used for new conversations; defaults to the current checkout | | `VITE_WORKER_URLS` | Optional worker URLs for Browser integrations | | `VITE_ENABLE_BROWSER_TOOLS` | Disable browser tools for new conversations when set to `false` | | `VITE_LOAD_PUBLIC_SKILLS` | Enable loading public skills when set to `true` | @@ -73,6 +94,8 @@ The development stack also supports source and version overrides for the agent s - `OH_AGENT_SERVER_GIT_REF` - `OH_AGENT_SERVER_VERSION` +When more than one is set, the effective precedence is local source path, then git ref, then pinned version. + These are useful when you are developing Agent Canvas alongside a local `software-agent-sdk` checkout. ## Learn More diff --git a/openhands/usage/agent-canvas/overview.mdx b/openhands/usage/agent-canvas/overview.mdx index 81ee582df..b7326f8e9 100644 --- a/openhands/usage/agent-canvas/overview.mdx +++ b/openhands/usage/agent-canvas/overview.mdx @@ -38,7 +38,7 @@ When you run `agent-canvas`, you get a complete local stack: ## Where to Start -- [Setup](/openhands/usage/agent-canvas/setup) — Install Agent Canvas globally from npm and run it from your terminal. +- [Setup](/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. - [Automations](/openhands/usage/agent-canvas/automations) — Work with the bundled automation backend. diff --git a/openhands/usage/agent-canvas/self-hosting.mdx b/openhands/usage/agent-canvas/self-hosting.mdx index 7cd1e6307..57c87d3ce 100644 --- a/openhands/usage/agent-canvas/self-hosting.mdx +++ b/openhands/usage/agent-canvas/self-hosting.mdx @@ -30,19 +30,23 @@ Before you expose Agent Canvas to a broader network, make sure you: 1. Provision a Linux or macOS machine you control. 2. Install Node.js, npm, and `uv`. -3. Install Agent Canvas globally: +3. Clone the repository and install dependencies: ```bash -npm install -g @openhands/agent-canvas +git clone https://github.com/OpenHands/agent-canvas.git +cd agent-canvas +npm install ``` -4. Start Agent Canvas: +4. Start the local stack: ```bash -agent-canvas +npm run dev ``` -5. Put a reverse proxy such as nginx in front of it if you need browser access beyond localhost. +5. Put a reverse proxy such as nginx in front of the ingress endpoint if you need browser access beyond localhost. + +That stack keeps the ingress, frontend, agent server, and automation backend bound to `127.0.0.1`, so the network and reverse-proxy layers are what determine who can reach it. ## Reverse Proxy and Auth diff --git a/openhands/usage/agent-canvas/setup.mdx b/openhands/usage/agent-canvas/setup.mdx index 83b36ffd3..ef9f4a908 100644 --- a/openhands/usage/agent-canvas/setup.mdx +++ b/openhands/usage/agent-canvas/setup.mdx @@ -3,7 +3,7 @@ title: Setup description: Install Agent Canvas from npm and run it from your terminal. --- -This page documents the recommended install path for Agent Canvas: install the published package globally with npm, then start it with the `agent-canvas` command. +This page documents the published npm install path for Agent Canvas: install the package globally, then start it with the `agent-canvas` command. ## Prerequisites From 8ef54efaf3b0bf20cd66a4604a496c9482063910 Mon Sep 17 00:00:00 2001 From: Devin Date: Tue, 26 May 2026 21:12:31 -0400 Subject: [PATCH 5/6] Misc Updates round one - Replaced CLI in quickstart with Enterprise. Now Cloud, Enterprise, Canvas - Capitalize a few spots - Remove plugins coming soon - Added link to main Automations creation guide --- openhands/usage/agent-canvas/automations.mdx | 22 ++++++++++--------- .../agent-canvas/customize-and-settings.mdx | 7 +++--- overview/quickstart.mdx | 10 ++++----- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/openhands/usage/agent-canvas/automations.mdx b/openhands/usage/agent-canvas/automations.mdx index 7413b2c27..5fd9f8b0d 100644 --- a/openhands/usage/agent-canvas/automations.mdx +++ b/openhands/usage/agent-canvas/automations.mdx @@ -7,12 +7,12 @@ Agent Canvas can work with the OpenHands automation backend so you can run agent ## What You Can Do -In the `Automations` view, you can: +In the `Automate` view, you can: -- browse existing automations -- inspect automation configuration and activity -- enable or disable automations -- work with recommended automation flows +- Browse existing automations +- Inspect automation configuration and activity +- Enable or disable automations +- Work with recommended automation flows ## How Creation Flows Usually Start @@ -20,8 +20,10 @@ The `Automations` view is mainly for browsing and managing automations that alre 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 +- 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/creating-automations). ## Local Stack Behavior @@ -29,9 +31,9 @@ When you start Agent Canvas with the `agent-canvas` command, the local stack inc That makes the built-in local setup a good starting point for: -- scheduled maintenance tasks -- event-driven coding workflows -- testing automation ideas before deploying them elsewhere +- Scheduled maintenance tasks +- Event-driven coding workflows +- Testing automation ideas before deploying them elsewhere ## Backend Availability Matters diff --git a/openhands/usage/agent-canvas/customize-and-settings.mdx b/openhands/usage/agent-canvas/customize-and-settings.mdx index a5186562a..54a8d4b14 100644 --- a/openhands/usage/agent-canvas/customize-and-settings.mdx +++ b/openhands/usage/agent-canvas/customize-and-settings.mdx @@ -14,7 +14,6 @@ Open the top-level `Customize` area to manage: - `Skills` - `MCP Servers` -- `Plugins` (currently marked `Coming Soon`) Use the section navigation inside `Customize` to switch between those pages. @@ -41,9 +40,9 @@ On local backends, the `LLM` page also includes an `Available Profiles` area for Each settings section is synced with the **active backend**. That means: -- changing backends changes which settings you are editing -- a setting saved for one backend does not automatically apply to every other backend -- the available options can differ depending on backend capabilities +- Changing backends changes which settings you are editing +- A setting saved for one backend does not automatically apply to every other backend +- The available options can differ depending on backend capabilities ## Practical Example diff --git a/overview/quickstart.mdx b/overview/quickstart.mdx index e8871c8ab..df545a6c6 100644 --- a/overview/quickstart.mdx +++ b/overview/quickstart.mdx @@ -15,12 +15,12 @@ Get started with OpenHands in minutes. Choose the option that works best for you - No installation needed - Managed infrastructure - - Use OpenHands from your terminal. Perfect for automation and scripting. + + Deploy OpenHands on your own infrastructure with the Enterprise Quick Start. - - IDE integrations available - - Headless mode for CI/CD - - Lightweight installation + - Self-hosted for teams and organizations + - Managed platform components on your infrastructure + - Guided setup from the Enterprise Quick Start Install Agent Canvas from npm and run it from your terminal. From 329919eca83b8672484692552f4ea9c6f8471ddb Mon Sep 17 00:00:00 2001 From: Devin Date: Tue, 26 May 2026 21:24:57 -0400 Subject: [PATCH 6/6] Fix the new automations link --- openhands/usage/agent-canvas/automations.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openhands/usage/agent-canvas/automations.mdx b/openhands/usage/agent-canvas/automations.mdx index 5fd9f8b0d..52d7020de 100644 --- a/openhands/usage/agent-canvas/automations.mdx +++ b/openhands/usage/agent-canvas/automations.mdx @@ -23,7 +23,7 @@ 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/creating-automations). +Visit the Automations Docs have a more [detailed guide on creating automations](/openhands/usage/automations/creating-automations). ## Local Stack Behavior