diff --git a/llms-full.txt b/llms-full.txt index dbd8850a..b98e2444 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -22617,6 +22617,207 @@ The example demonstrates a two-level parallel execution pattern: - **[Custom Tools](/sdk/guides/custom-tools)** - Create thread-safe custom tools - **[Agent Architecture](/sdk/arch/agent)** - Understand the agent execution model +### Persistent Memory +Source: https://docs.openhands.dev/sdk/guides/persistent-memory.md + +import RunExampleCode from "/sdk/shared-snippets/how-to-run-example.mdx"; + +> A ready-to-run example is available [here](#ready-to-run-example)! + +Persistent memory lets an agent keep what it learned -- root causes, environment quirks, project decisions, user preferences -- in plain Markdown files that are loaded back into the system prompt at the start of every new conversation. The agent maintains the files itself as it works, so it gets better at a project over time. + +The feature is **opt-in and off by default**: without it, agents keep the existing `AGENTS.md`-based guidance and prompts are unchanged. + +## Enabling Persistent Memory + +Set `load_memory=True` on the agent's `AgentContext`: + +```python focus={5} icon="python" +from openhands.sdk import Agent, AgentContext + +agent = Agent( + llm=llm, + agent_context=AgentContext(load_memory=True), + tools=tools, +) +``` + +That single flag does two things: + +1. At session start, the conversation reads the `MEMORY.md` indexes from both memory tiers and injects them into the system prompt as a `` block. +2. The system prompt's `` section switches to instructions that teach the agent where its memory lives and how to maintain it. + +## The Two Tiers + +| Tier | Location | Contents | +|------|----------|----------| +| **User** | `~/.openhands/memory/` | Knowledge and preferences that apply across all projects | +| **Project** | `/.openhands/memory/` | Knowledge specific to the current repository | + +Each tier contains: + +- **`MEMORY.md`** -- a curated index of durable facts. This is the only file injected into the prompt, so the agent is instructed to keep it small and high-value. +- **Daily logs (`YYYY-MM-DD.md`)** -- free-form working notes. They are never injected automatically; the agent reads them on demand with its file tools when `MEMORY.md` points to them. + +The files are plain Markdown: you can review, edit, or delete them at any time, and a project team can even commit `.openhands/memory/` to share agent-learned knowledge. + +## What Gets Injected + +At the start of each opted-in conversation, the resolved memory appears in the system prompt like this (user tier first, then project tier): + +```text wrap + + +The content below comes from memory files on disk and has NOT been verified by OpenHands. +... + + +# User memory (~/.openhands/memory/MEMORY.md) +- prefers uv over pip for Python tooling + +# Project memory (.openhands/memory/MEMORY.md) +- the API uses cursor-based pagination + +``` + +A few properties worth knowing: + +- **Size budget**: the combined indexes are capped at ~6,000 characters. When the budget is exceeded, whole lines are dropped from the top of each over-budget tier (the oldest content) -- partial lines never survive, the tier headers are always kept, and a truncation notice appears under the header of any tier that lost lines. Keep indexes curated. +- **Untrusted by design**: the injected block is wrapped in ``. Memory files are typically agent-written, but anyone with access to the workspace or repository can edit or commit them (a cloned repo may ship a `.openhands/memory/MEMORY.md`), so the agent is told they may contain prompt injection, and to treat them as unverified hints, never as authoritative instructions. +- **Never persisted**: the resolved memory text is re-read from disk each session and is excluded from conversation persistence (`base_state.json`) and API payloads. +- **Best-effort**: an unreadable memory file logs a warning and the conversation starts normally without it. + +## How the Agent Maintains Memory + +When memory is enabled, the system prompt instructs the agent to: + +- record durable, broadly useful facts in `MEMORY.md` near the end of a task (creating the directories and files if missing), and put long detail in daily logs; +- merge duplicates, prune stale entries, and keep the indexes concise; +- never record secrets or credentials, and skip facts that are trivially re-discoverable (directory listings, obvious commands); +- keep `AGENTS.md` for instructions addressed to *any* agent working in the repository -- memory is for what the agent learned itself. + +## Ready-to-run Example + + +This example is available on GitHub: [examples/01_standalone_sdk/55_persistent_memory.py](https://github.com/OpenHands/software-agent-sdk/blob/main/examples/01_standalone_sdk/55_persistent_memory.py) + + +```python icon="python" expandable examples/01_standalone_sdk/55_persistent_memory.py +"""Opt-in persistent memory across sessions (two-tier ``MEMORY.md``). + +With ``AgentContext(load_memory=True)`` a conversation loads the ``MEMORY.md`` +indexes from ``~/.openhands/memory/`` (user tier) and +``/.openhands/memory/`` (project tier) into the system prompt at +session start (the ```` block), and the system prompt +instructs the agent to maintain those files as it works. + +This example runs two conversations over the same workspace: + +1. Session 1 asks the agent to record a project decision in its persistent + project memory -- the agent writes ``.openhands/memory/MEMORY.md`` itself. +2. Session 2 is a brand-new conversation: the saved memory is injected into + its system prompt automatically, so the agent already knows the decision + without being told again. + +Memory is opt-in and off by default. The example only writes inside a +temporary workspace; the user tier under ``~`` is left untouched. +""" + +import os +import tempfile +from pathlib import Path + +from pydantic import SecretStr + +from openhands.sdk import LLM, Agent, AgentContext, Conversation, get_logger +from openhands.sdk.event import SystemPromptEvent +from openhands.sdk.tool import Tool +from openhands.tools.file_editor import FileEditorTool +from openhands.tools.terminal import TerminalTool + + +logger = get_logger(__name__) + +# Configure LLM +api_key = os.getenv("LLM_API_KEY") +assert api_key is not None, "LLM_API_KEY environment variable is not set." +model = os.getenv("LLM_MODEL", "gpt-5.5") +base_url = os.getenv("LLM_BASE_URL") +llm = LLM( + usage_id="agent", + model=model, + base_url=base_url, + api_key=SecretStr(api_key), +) + +tools = [Tool(name=TerminalTool.name), Tool(name=FileEditorTool.name)] + +# Opt in to persistent memory. Everything else is automatic: the conversation +# resolves the MEMORY.md indexes at session start, and the system prompt tells +# the agent how to maintain them. +agent_context = AgentContext(load_memory=True) + +with tempfile.TemporaryDirectory() as workspace: + memory_index = Path(workspace) / ".openhands" / "memory" / "MEMORY.md" + + print("=" * 100) + print("Session 1: ask the agent to record a decision in project memory.") + agent = Agent(llm=llm, tools=tools, agent_context=agent_context) + conversation = Conversation(agent=agent, workspace=workspace) + conversation.send_message( + "We just decided to use `uv` (not pip/poetry) for all Python " + "dependency management in this project. Record that decision in your " + "persistent project memory so future sessions know it." + ) + conversation.run() + conversation.close() + + print("=" * 100) + print(f"Project memory after session 1 ({memory_index}):") + if memory_index.exists(): + print(memory_index.read_text()) + else: + print("(the agent did not create the memory index)") + + print("=" * 100) + print("Session 2: a brand-new conversation over the same workspace.") + agent = Agent(llm=llm, tools=tools, agent_context=agent_context) + conversation = Conversation(agent=agent, workspace=workspace) + conversation.send_message( + "Which tool do we use for Python dependency management in this " + "project? Answer from what you already know about the project." + ) + conversation.run() + + # The recorded memory was injected into session 2's system prompt as the + # block -- show it to make the mechanism visible. + system_prompt_event = next( + event + for event in conversation.state.events + if isinstance(event, SystemPromptEvent) + ) + dynamic_context = system_prompt_event.dynamic_context + injected = dynamic_context.text if dynamic_context else "" + print("=" * 100) + print( + " injected into session 2's system prompt: " + f"{'' in injected}" + ) + conversation.close() + +# Report cost +cost = llm.metrics.accumulated_cost +print(f"EXAMPLE_COST: {cost}") +``` + + + +## Next Steps + +- **[Skills](/sdk/guides/skill)** - Inject reusable instructions and context into agents +- **[Context Condenser](/sdk/guides/context-condenser)** - Keep long conversations within the context window +- **[Persistence](/sdk/guides/convo-persistence)** - Save and restore conversation state across sessions + ### Plugins Source: https://docs.openhands.dev/sdk/guides/plugins.md @@ -23472,7 +23673,14 @@ def _print_action_preview(pending_actions) -> None: print(f"\nπŸ” Agent created {len(pending_actions)} action(s) awaiting confirmation:") for i, action in enumerate(pending_actions, start=1): snippet = str(action.action)[:100].replace("\n", " ") - print(f" {i}. {action.tool_name}: {snippet}...") + # Lead with the LLM's natural-language summary when available, keeping + # the raw action snippet as secondary detail. When no summary was + # provided, the raw action itself is the most useful headline. + if action.summary: + print(f" {i}. [{action.tool_name}] {action.summary}") + print(f" {snippet}...") + else: + print(f" {i}. [{action.tool_name}] {snippet}...") def confirm_in_console(pending_actions) -> bool: @@ -23680,7 +23888,14 @@ def _print_blocked_actions(pending_actions) -> None: print(f"\nπŸ”’ Security analyzer blocked {len(pending_actions)} high-risk action(s):") for i, action in enumerate(pending_actions, start=1): snippet = str(action.action)[:100].replace("\n", " ") - print(f" {i}. {action.tool_name}: {snippet}...") + # Lead with the LLM's natural-language summary when available, keeping + # the raw action snippet as secondary detail. When no summary was + # provided, the raw action itself is the most useful headline. + if action.summary: + print(f" {i}. [{action.tool_name}] {action.summary}") + print(f" {snippet}...") + else: + print(f" {i}. [{action.tool_name}] {snippet}...") def confirm_high_risk_in_console(pending_actions) -> bool: @@ -36301,7 +36516,7 @@ Custom LLM configurations are only available when using OpenHands in development ### Google Gemini/Vertex Source: https://docs.openhands.dev/openhands/usage/llms/google-llms.md -## Gemini - Google AI Studio Configs +## Gemini - Google AI Studio Configuration When running OpenHands, you'll need to set the following in the OpenHands UI through the Settings under the `LLM` tab: - `LLM Provider` to `Gemini` @@ -36310,7 +36525,7 @@ If the model is not in the list, enable `Advanced` options, and enter it in `Cus (e.g. gemini/<model-name> like `gemini/gemini-2.0-flash`). - `API Key` to your Gemini API key -## VertexAI - Google Cloud Platform Configs +## VertexAI - Google Cloud Platform Configuration To use Vertex AI through Google Cloud Platform when running OpenHands, you'll need to set the following environment variables using `-e` in the docker run command: @@ -36327,6 +36542,85 @@ Then set the following in the OpenHands UI through the Settings under the `LLM` If the model is not in the list, enable `Advanced` options, and enter it in `Custom Model` (e.g. vertex_ai/<model-name>). +### Vertex AI Dependencies + +The `vertex_ai/*` models (including Gemini and Claude via Vertex AI) require the +`google-cloud-aiplatform` package, which is **not included by default** in the published +agent-server image. How you enable it depends on your deployment: + + +Unlike AWS Bedrock (whose `boto3` dependency is bundled by default), Vertex AI support is +opt-in. If you skip this step, you will see a ModuleNotFoundError: No module named +'vertexai' error when the agent tries to call a Vertex AI model. + + +#### Local / Non-Docker Install + +Install the `vertex` extra in your Python environment: + +```bash +pip install "openhands-sdk[vertex]" +# or, with uv (works in any Python environment): +uv pip install "openhands-sdk[vertex]" +``` + +#### Custom Agent-Server Image + +Build the image with the `ENABLE_VERTEX` build flag (the container build file is in the +[`software-agent-sdk` repo](https://github.com/OpenHands/software-agent-sdk/blob/main/openhands-agent-server/openhands/agent_server/docker/Dockerfile); +run from the repo root): + +```bash +docker build \ + --build-arg ENABLE_VERTEX=1 \ + -t my-agent-server:vertex \ + -f openhands-agent-server/openhands/agent_server/docker/Dockerfile \ + . +``` + +Then point OpenHands at your custom image via the `AGENT_SERVER_IMAGE_REPOSITORY` and +`AGENT_SERVER_IMAGE_TAG` environment variables (see the +[Custom Sandbox Guide](/openhands/usage/advanced/custom-sandbox-guide) for details). + +#### OpenHands Enterprise (Replicated / Kubernetes) + +The default OHE installer Vertex path routes LLM calls through a LiteLLM proxy β€” the +agent-server uses a `litellm_proxy/...` model, and the proxy makes the actual Vertex call. +So the agent-server image does **not** need Vertex enabled for the default path; `ENABLE_VERTEX=1` +is only relevant if you customize OHE to bypass the proxy and call `vertex_ai/*` directly from +the agent-server. + +### Claude via Vertex AI + +If you route Anthropic Claude through Google Vertex AI / Model Garden (rather than direct +Anthropic endpoints), use the `vertex_ai/` prefix with the Vertex-published model name, +which is date-stamped: + +- `Custom Model`: `vertex_ai/claude-sonnet-4-5@20250929` + +Use the exact model name shown in your Vertex AI Model Garden console. + + +For `vertex_ai/*` models, OpenHands still needs google-cloud-aiplatform +from the `vertex` extra above. In custom Claude via Vertex AI setups, if you encounter +ModuleNotFoundError: No module named 'anthropic', install the Anthropic SDK too: +pip install "anthropic[vertex]". + + +### Troubleshooting + +#### Vertex AI SDK Import Error + +If you encounter this error: +``` +litellm.BadRequestError: Vertex_aiException BadRequestError - vertexai import failed +please run `pip install -U "google-cloud-aiplatform>=1.38"`. +Got error: No module named 'vertexai' +``` + +This means the agent-server image does not include the Vertex AI SDK. Enable the `vertex` +extra as described in [Vertex AI Dependencies](#vertex-ai-dependencies) above. + ### Groq Source: https://docs.openhands.dev/openhands/usage/llms/groq.md @@ -46924,7 +47218,7 @@ OpenHands Enterprise consists of several components deployed as Kubernetes workl | Component | Description | |-----------|-------------| | **OpenHands Server** | Main application server handling UI, API, and agent orchestration | -| **Runtime API** | Manages sandbox lifecycleβ€”provisioning, scaling, and cleanup | +| **Runtime API** | Manages sandbox lifecycle: provisioning, scaling, and cleanup | | **Runtimes (Sandboxes)** | Isolated containers where agents execute code | | **Keycloak** | Identity and access management | | **LiteLLM Proxy** | Routes requests to your LLM provider(s) | @@ -46944,6 +47238,18 @@ OpenHands Enterprise consists of several components deployed as Kubernetes workl End-to-end installation instructions using your OpenHands Enterprise license. + + Install the Sysbox runtime so agent sandboxes can run securely. + + + + Automate DNS records and TLS certificates with external-dns and cert-manager. + + + + Prepare an Amazon EKS cluster to run OpenHands Enterprise. + + Configure OpenHands to use your own PostgreSQL database instead of the bundled instance. @@ -46962,6 +47268,272 @@ please contact our team to discuss your requirements. Get in touch with our team to request access to Kubernetes installation. +### DNS and TLS +Source: https://docs.openhands.dev/enterprise/k8s-install/dns-and-tls.md + +OpenHands needs DNS records and TLS certificates for its hostnames. We recommend automating both with +**external-dns** and **cert-manager**, which run on any Kubernetes distribution and support the major +cloud DNS providers. If you can't run them, provision the records and certificates by hand, see +[Manual Setup](#manual-setup). + +## Hostnames + +OpenHands serves these hostnames, using `openhands.example.com` as the base domain (matching the +[Helm install](/enterprise/k8s-install/installation)): + +| Hostname | Purpose | +|---|---| +| `app.openhands.example.com` | Application | +| `auth.app.openhands.example.com` | Login (Keycloak) | +| `runtime-api.openhands.example.com` | Runtime API | +| `*.runtime.openhands.example.com` | Per-session sandboxes | + +All of these must resolve to your ingress load balancer. The sandbox entry must be a **wildcard** +because each session gets its own subdomain. + +## external-dns + +external-dns watches your Ingresses and Services and creates the matching DNS records automatically. + +- Install it from its [Helm chart](https://kubernetes-sigs.github.io/external-dns/). +- Set `provider` to your DNS provider and grant it access to your zone (the access mechanism is + provider-specific). +- Recommended settings: + +```yaml +provider: + name: aws # or google, azure, cloudflare, ... +policy: upsert-only # only ever create/update, never delete +registry: txt +txtOwnerId: openhands +domainFilters: + - openhands.example.com # only manage names under your base domain +``` + +With `upsert-only` and a TXT registry, external-dns only ever touches records it created. + +## cert-manager + +cert-manager issues and renews certificates from Let's Encrypt. Use the **DNS-01** challenge, the +only one that can issue the **wildcard** certificate the sandbox hostnames need. + + + + Install it from its [Helm chart](https://cert-manager.io/docs/installation/helm/), and grant it + access to your DNS provider so it can solve DNS-01 challenges. + + + The `solvers` block is specific to your DNS provider. The Route 53 solver is shown here. + + ```yaml + apiVersion: cert-manager.io/v1 + kind: ClusterIssuer + metadata: + name: letsencrypt-prod + spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + email: you@example.com + privateKeySecretRef: + name: letsencrypt-prod + solvers: + - dns01: + route53: # swap for cloudDNS, azureDNS, cloudflare, ... + hostedZoneID: + ``` + + + Start with the staging server (`https://acme-staging-v02.api.letsencrypt.org/directory`) while + you get the setup working (generous rate limits), then switch to production. + + + + A single wildcard covers every sandbox host. With Traefik, serve it as the default `TLSStore` so + no per-ingress TLS config is needed. + + ```yaml + apiVersion: cert-manager.io/v1 + kind: Certificate + metadata: + name: runtime-wildcard + namespace: openhands + spec: + secretName: runtime-wildcard-tls + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer + dnsNames: + - "*.runtime.openhands.example.com" + ``` + + Issue certificates for the `app`, `auth`, and `runtime-api` hosts the same way. + + + +## Manual Setup + +If you don't run external-dns and cert-manager, provision these by hand and point the ingress +controller at them. + +**DNS**: create a record for each hostname in the table above, all pointing to your ingress load +balancer (typically a CNAME to the load balancer's hostname, or a cloud DNS alias). The sandbox +record must be the wildcard `*.runtime.openhands.example.com`. + +**TLS**: obtain certificates covering those hostnames and load them into the ingress controller as +Kubernetes TLS secrets. A single wildcard isn't enough, because the hostnames sit at different +depths. You need: + +- `*.runtime.openhands.example.com` for the sandboxes, and +- certificates for `app.openhands.example.com`, `auth.app.openhands.example.com`, and + `runtime-api.openhands.example.com` (for example a `*.openhands.example.com` wildcard, which covers + `app` and `runtime-api`, plus a certificate for `auth.app.openhands.example.com`). + +## Next Steps + + + + Install the sandbox runtime on your sandbox nodes. + + + Deploy OpenHands once the cluster is ready. + + + +### Amazon EKS +Source: https://docs.openhands.dev/enterprise/k8s-install/eks.md + +Running OpenHands Enterprise on Amazon EKS follows the standard +[Helm install](/enterprise/k8s-install/installation), with a few EKS-specific choices for node +pools, storage, ingress, and the sandbox runtime. This guide covers preparing the cluster. Once +it's ready, follow the Helm install to deploy. + +## Cluster Requirements + +| Requirement | Recommendation | +|---|---| +| EKS version | A currently-supported version that [Sysbox](/enterprise/k8s-install/sysbox) supports | +| Add-ons | VPC CNI, CoreDNS, kube-proxy, and the **EBS CSI driver** (sandboxes and stateful components use EBS volumes) | +| Storage class | A `gp3` StorageClass backed by the EBS CSI driver | +| Metrics | Metrics Server, for `kubectl top` and autoscaling | + +Set `runtime-api.env.STORAGE_CLASS` to your `gp3` class. + +## Node Pools + +We recommend using two separate node pools: a **general** pool for the OpenHands application services +and cluster add-ons, and a **Sysbox** pool for the agent sandboxes. Keeping sandboxes on their own +pool isolates the untrusted sandbox workload from your services, and lets the sandbox pool scale +independently, since sandboxes are created and torn down far more frequently than the services. + +- **General pool**: Use standard EKS nodes on the Amazon Linux 2023 AMI, with on-demand or Spot + capacity. +- **Sysbox pool**: Sandboxes need the Sysbox runtime, which requires an Ubuntu AMI, at least 4 vCPU + per node, and on-demand capacity. See [Installing Sysbox](/enterprise/k8s-install/sysbox). + +We recommend [Karpenter](https://karpenter.sh/) for autoscaling both pools (managed node groups also +work). Size the Sysbox pool by peak concurrent sessions, and configure it so a node is only removed +when empty, never while a session is running. + +Sandboxes are pinned to the Sysbox pool automatically by the `sysbox-runc` RuntimeClass. Keep the +OpenHands services and add-ons on the general pool with a node selector. + +### Sizing the Sandbox Nodes + +Per-sandbox CPU, memory, and ephemeral storage are set on the +[Resource Limits](/enterprise/k8s-install/resource-limits) page. Size your Sysbox nodes around the +values you choose there. With the defaults (**0.5 vCPU**, **3 GiB memory**, **10 GiB** ephemeral), +memory is usually the binding constraint, so `m`-family instances (4 GiB per vCPU) pack most +efficiently: + +| Instance | vCPU / memory | Sandboxes per node | Bound by | +|---|---|---|---| +| `c6i.2xlarge` | 8 / 16 GiB | ~4 | memory | +| `m6i.2xlarge` | 8 / 32 GiB | ~9 | memory | +| `r6i.2xlarge` | 8 / 64 GiB | ~14 | CPU | +| `m6i.4xlarge` | 16 / 64 GiB | ~19 | memory | + +Recompute these counts whenever you change the sandbox size. Also size for two more things: + +- **Root volume**: ephemeral scratch is the per-sandbox ephemeral request Γ— sandboxes per node. At + the default 10 GiB, a full `m6i.4xlarge` needs ~190 GiB, so give Sysbox nodes a large root volume + (200 GiB or more), or prefer more, smaller nodes. +- **Warm capacity**: a new sandbox otherwise waits for a node to boot, which takes a few minutes. + Keeping a small pool of spare capacity (for example a low-priority placeholder Deployment sized to + one sandbox) lets sessions start instantly. Size it to your expected burst. + +## Object Storage + +OpenHands stores conversation and session state in a file store. For production, we recommend using S3: + +1. Create a bucket in the cluster's region. +2. Grant access with either an IAM user access key scoped to the bucket, or IRSA / EKS Pod Identity to + avoid a long-lived credential. +3. For the access-key approach, store the credentials in a secret: + +```bash +kubectl -n openhands create secret generic openhands-s3-credentials \ + --from-literal=AWS_ACCESS_KEY_ID= \ + --from-literal=AWS_SECRET_ACCESS_KEY= +``` + +Then point the file store at the bucket in your values: + +```yaml +filestore: + ephemeral: false + type: s3 + bucket: + region: + existingSecret: openhands-s3-credentials +``` + +## Database + +Use an external **Amazon RDS for PostgreSQL** instance rather than the bundled database. Place it in +the cluster's VPC, reachable from the nodes on port 5432. See +[External PostgreSQL](/enterprise/external-postgres) for the values. + +## Ingress + +Install an ingress controller on the general pool and expose it with an **AWS Network Load +Balancer**, provisioned directly from Service annotations (no AWS Load Balancer Controller required). +Both Traefik and NGINX are supported: + +- **Traefik (recommended)**: set `ingress.class: traefik` in your OpenHands values. Its default + `TLSStore` lets one wildcard certificate serve every host. +- **NGINX**: set `ingress.class: nginx` and use `nginx.ingress.kubernetes.io/*` annotations for + per-ingress tuning. + +Expose the controller's Service as an NLB in the controller's own chart values: + +```yaml +service: + type: LoadBalancer + annotations: + service.beta.kubernetes.io/aws-load-balancer-type: nlb + service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing +``` + +Then set up certificates and DNS records for the OpenHands hostnames, see +[DNS and TLS](/enterprise/k8s-install/dns-and-tls). + +## Next Steps + + + + Install the sandbox runtime on your Sysbox pool. + + + Automate records and certificates with external-dns and cert-manager. + + + Deploy OpenHands once the cluster is ready. + + + Size memory, CPU, and replicas for production. + + + ### Install with Helm Source: https://docs.openhands.dev/enterprise/k8s-install/installation.md @@ -46971,14 +47543,15 @@ license automatically at install time. Helm-based installation requires an OpenHands Enterprise license. If you don't have - one yet, [contact our team](https://openhands.dev/contact) to get set up. + one yet, [register for a free 30-day trial](https://install.r9.all-hands.dev/openhands/signup) + or [contact our team](https://openhands.dev/contact) to get set up. ## Prerequisites - A Kubernetes cluster with a default storage class and an ingress controller (see [Resource Limits](/enterprise/k8s-install/resource-limits) for sizing guidance) -- **Helm v3.18 or later** +- **Helm v4 or later** - `kubectl` access to the target cluster - Your **license ID** and the **email address** registered with your license (both provided by our team) @@ -47006,14 +47579,21 @@ helm registry login registry.replicated.com \ --password ``` -## Step 2: Create the namespace and secrets +## Step 2: Create the namespaces and secrets -The chart references several Kubernetes secrets that you create ahead of installation: +We recommend running agent sandboxes in a namespace separate from the +application. Sandboxes run agent-authored code, so a dedicated namespace keeps +them isolated from the application, database, and secrets. Create both +namespaces now: ```bash kubectl create namespace openhands +kubectl create namespace openhands-runtimes ``` +The chart references several Kubernetes secrets that you create ahead of +installation, all in the `openhands` namespace: + ```bash kubectl -n openhands create secret generic jwt-secret \ --from-literal=jwt-secret= @@ -47086,6 +47666,16 @@ cluster; the bundled PostgreSQL needs a database name and database creation turned on, both shown below (to use your own database instead, see [External PostgreSQL](/enterprise/external-postgres)). + + The embedded PostgreSQL is intended for proof-of-concept and evaluation use + only, not production. For production deployments we recommend bringing your + own managed PostgreSQL β€” see + [External PostgreSQL](/enterprise/external-postgres). There is no officially + supported migration path from the embedded PostgreSQL instance to an external + one, so plan to switch to an external database before you load production + data. + + The example below uses Traefik, the chart's default ingress class; set `ingress.class` and the annotations to match your controller. @@ -47131,6 +47721,9 @@ env: LITELLM_DEFAULT_MODEL: litellm_proxy/claude-sonnet-4-5 runtime-api: + # Create sandboxes in the dedicated namespace from Step 2, isolated from the + # application workloads. + sandbox_namespace: openhands-runtimes ingress: enabled: true host: runtime-api.openhands.example.com @@ -47252,7 +47845,7 @@ support-bundle upload support-bundle-.tar.gz | Symptom | Likely cause | |---------|--------------| -| `helm install` fails with a template error mentioning `replicated` | Helm version too old β€” upgrade to v3.18+ | +| `helm install` fails with a template error mentioning `replicated` | Helm version too old β€” upgrade to v4+ | | `helm registry login` or chart pull returns 401/403 | License credentials incorrect, or the license isn't enabled for Helm installs β€” contact support | | Preflight warns about node memory | Cluster nodes below the recommended sizing β€” see [Resource Limits](/enterprise/k8s-install/resource-limits) | @@ -47531,6 +48124,94 @@ For production deployments, we recommend integrating with a monitoring solution +### Installing Sysbox +Source: https://docs.openhands.dev/enterprise/k8s-install/sysbox.md + +OpenHands runs each agent session in a sandbox that uses [Sysbox](https://github.com/nestybox/sysbox) +for isolation. This guide covers installing Sysbox. + +## Node Requirements + +Sysbox nodes must: + +- Run a Sysbox-supported Linux distribution. **Ubuntu** is the most common and best-supported choice. +- Have at least **4 vCPU** and 4 GiB of memory. +- Use containerd (the default on most managed distributions). +- Run a Kubernetes version [supported by Sysbox](https://github.com/nestybox/sysbox/blob/master/docs/user-guide/install-k8s.md). + +Run sandboxes on a **dedicated node pool** so these requirements (and the Sysbox install below) +apply only to sandbox nodes, not the whole cluster. + + + On **Amazon EKS**, use Canonical's EKS-optimized Ubuntu AMI for the sandbox node pool. The default + Amazon Linux AMI isn't supported. See [Amazon EKS](/enterprise/k8s-install/eks#node-pools) for the + full node-pool setup. + + +## Install Sysbox + +Sysbox installs per node via the `sysbox-deploy-k8s` DaemonSet. It targets nodes labeled +`sysbox-install=yes`, installs the runtime, and registers a `sysbox-runc` RuntimeClass. + + + + ```bash + kubectl label nodes sysbox-install=yes + ``` + + If your nodes autoscale, set this label on the group so every node it launches is labeled + automatically. + + + ```bash + kubectl apply -f https://raw.githubusercontent.com/nestybox/sysbox/master/sysbox-k8s-manifests/sysbox-install.yaml + ``` + + + ```bash + kubectl get runtimeclass sysbox-runc + ``` + + + +The `sysbox-runc` RuntimeClass pins any pod that uses it to Sysbox nodes, so sandboxes only schedule +where the runtime is installed. + +## Point OpenHands at Sysbox + +Tell the runtime API to launch sandboxes with the Sysbox runtime class, and enable native user +namespaces: + +```yaml +runtime-api: + env: + RUNTIME_CLASS: sysbox-runc + SET_HOST_USERS: "true" +``` + +## Verify + +Start a conversation in OpenHands, then confirm the sandbox pod landed on a Sysbox node with the +runtime class applied: + +```bash +kubectl get pod -n openhands \ + -o jsonpath='{.spec.runtimeClassName}{"\n"}' +``` + +The output should be `sysbox-runc`. + +## Next Steps + + + + Set up records and certificates for the OpenHands hostnames. + + + Deploy OpenHands once the cluster is ready. + + + ### Plugin Marketplace Source: https://docs.openhands.dev/enterprise/plugin-marketplace.md @@ -47781,6 +48462,13 @@ You will need a VM to host OpenHands Enterprise. Choose one of the options below Follow the README instructions to configure and apply the Terraform configuration. + + + The recommended Terraform path provisions a publicly trusted TLS certificate. If you bring + your own certificate instead, use a publicly trusted CA whenever possible. Private CA + certificates require every external webhook or OAuth provider that calls OpenHands to trust + your CA. + @@ -48020,6 +48708,11 @@ If the install command fails after preflight checks pass, run `sudo ./openhands If you provisioned manually and have your own certificates on the VM, pass them the same way. You can also omit the `--tls-cert` and `--tls-key` flags and upload certificates later through the Admin Console. + + For trials and production deployments, use a publicly trusted TLS certificate whenever possible. + Private CA certificates may work for users after manual trust setup, but external integrations + such as GitHub, GitLab, Slack, Jira, and Bitbucket must also trust the certificate chain. If they + do not, webhook or OAuth callbacks can fail TLS verification and repeatedly retry. ![Installation commands](./images/install-commands.png) @@ -48040,6 +48733,9 @@ Click **Advanced**, then **Proceed** to continue to the Admin Console. If you did not provide certificates with the `install` command, select **"Upload your own"**, enter your base domain under **Hostname**, upload your private key and SSL certificate, then click **Continue**. +If you upload a private CA certificate, make sure any external webhook or OAuth provider that +calls OpenHands also trusts that CA. + ![Upload TLS certificate](./images/upload-tls-certificate.png) ### 6. Log in to the Admin Console @@ -48161,3 +48857,408 @@ OpenHands Enterprise is now running. You can open a repository or start a new co Explore the full OpenHands documentation for usage guides and features. + +### Release Notes +Source: https://docs.openhands.dev/enterprise/release-notes.md + +## 0.24.0 + +This release introduces a **Usage & Monitoring** dashboard, giving organization administrators visibility into AI spend and adoption across the organization. This dashboard provides high-level reports showing conversation counts, active sessions, and cost-per-conversation metrics, along with detailed conversation, user, and model-level breakdowns to help teams measure efficiency and ROI. + +The new **Budgets** feature -- also enabled for organization admins -- enables org-level spending limits with configurable alert thresholds (e.g., 80%, 90%, 100%) delivered via email or Slack. Default budgets and override budgets allow administrators to manage individual user spending limits. + +The **Settings β†’ Agent** page enables the use of third-party agents -- like Claude Code or Codex -- on OpenHands Enterprise sandboxes through the ACP (Agent Canvas Protocol) framework. + +Several additional Jira Cloud and Data CEnter enhancements have been made to improve overall integration experience. + +### Enterprise Server + +#### Features +* feat: implement semantic file chunking using tree-sitter AST parsing by @ysinghc in https://github.com/OpenHands/OpenHands/pull/14699 +* feat(org): Add organization conversation admin dashboard by @saurya in https://github.com/OpenHands/OpenHands/pull/14846 +* feat(app-server): capture production workspace state β€” initial snapshot at start + archive before delete (APP-2403) by @simonrosenberg in https://github.com/OpenHands/OpenHands/pull/14953 +* feat(device-verify): align warning, button color, and add workspace dropdown by @tofarr in https://github.com/OpenHands/OpenHands/pull/15031 +* feat(enterprise/auth): add super roles via user.role_id with permission fallback by @chuckbutkus in https://github.com/OpenHands/OpenHands/pull/14937 +* feat(org): expose caller permissions on GET /organizations/{id}/me by @VascoSch92 in https://github.com/OpenHands/OpenHands/pull/15048 +* feat(api-keys): add optional active window (not_before & expires_at) by @tofarr in https://github.com/OpenHands/OpenHands/pull/15085 +* feat(app-server): add repo/branch to Laminar trace metadata by @simonrosenberg in https://github.com/OpenHands/OpenHands/pull/15059 +* feat: add parallel tool calls (tool_concurrency_limit) to agent settings by @VascoSch92 in https://github.com/OpenHands/OpenHands/pull/14929 +* feat(api-keys): make 'unbound' org scope an explicit, first-class option by @tofarr in https://github.com/OpenHands/OpenHands/pull/15096 +* feat(jira-dc): fix the integration panel so members get guidance, not the admin setup form by @ak684 in https://github.com/OpenHands/OpenHands/pull/15040 +* feat: Add dynamic marketplace support for plugin registration by @HeyItsChloe in https://github.com/OpenHands/OpenHands/pull/14887 +* feat(saas-auth): accept api_key cookie as a fallback credential by @tofarr in https://github.com/OpenHands/OpenHands/pull/15101 +* feat(enterprise/auth): super-admin management endpoint (grant/revoke/list) by @jpshackelford in https://github.com/OpenHands/OpenHands/pull/15006 +* feat: rename admin dashboard to usage & monitoring by @saurya in https://github.com/OpenHands/OpenHands/pull/15146 +* feat: add SMTP email service by @saurya in https://github.com/OpenHands/OpenHands/pull/15144 +* feat: track user login timestamps by @saurya in https://github.com/OpenHands/OpenHands/pull/15148 +* feat: surface email enabled for smtp/resend by @saurya in https://github.com/OpenHands/OpenHands/pull/15185 +* feat: pass repository metadata to observability traces by @neubig in https://github.com/OpenHands/OpenHands/pull/14431 +* feat(enterprise): Agent Profiles on the cloud/SaaS backend (#15044) by @simonrosenberg in https://github.com/OpenHands/OpenHands/pull/15060 +* feat(backend): Add Budgets dashboard and expand Usage Dashboard by @saurya in https://github.com/OpenHands/OpenHands/pull/15149 +* feat: budgets and usage monitoring UI by @saurya in https://github.com/OpenHands/OpenHands/pull/15186 +* feat: surface email enabled for smtp/resend by @saurya in https://github.com/OpenHands/OpenHands/pull/15214 +* feat(app-server): enrich final archive manifests and remove initial snapshots by @simonrosenberg in https://github.com/OpenHands/OpenHands/pull/15058 +* feat(enterprise): make BYOR key alias pattern configurable by @tofarr in https://github.com/OpenHands/OpenHands/pull/15232 + +#### Bug Fixes +* fix(jira): make Jira Cloud and Jira DC HTTP timeouts configurable and consistent by @ak684 in https://github.com/OpenHands/OpenHands/pull/15012 +* fix: Fix CVE-2026-44681: Update authlib to >=1.6.12 by @mamoodi in https://github.com/OpenHands/OpenHands/pull/14983 +* fix: don't switch LLM profile before the conversation UUID exists (avoids 422) by @ak684 in https://github.com/OpenHands/OpenHands/pull/14900 +* fix(enterprise): log automation HTTP response failures as errors by @wgu9 in https://github.com/OpenHands/OpenHands/pull/15004 +* fix(enterprise): add alembic migration for execution_status column by @tofarr in https://github.com/OpenHands/OpenHands/pull/15030 +* fix(jira-dc): more forgiving repo + mention resolution for Data Center by @ak684 in https://github.com/OpenHands/OpenHands/pull/15034 +* fix(device-verify): rename 'Workspace' dropdown to 'Organization' by @tofarr in https://github.com/OpenHands/OpenHands/pull/15057 +* fix(jira-dc): don't org-gate a personal-workspace Jira DC integration by @ak684 in https://github.com/OpenHands/OpenHands/pull/15036 +* fix: stream LLM tokens for cloud conversations and profile switches by @VascoSch92 in https://github.com/OpenHands/OpenHands/pull/15021 +* fix: set email person property in PostHog during onboarding completion by @lilagrc in https://github.com/OpenHands/OpenHands/pull/15070 +* fix: Timezones stored in the db do not have a timezone by @tofarr in https://github.com/OpenHands/OpenHands/pull/15092 +* fix: add test for InMemoryRateLimiter.__init__ to prevent duplicate assignment regression by @aivong-openhands in https://github.com/OpenHands/OpenHands/pull/14729 +* fix(frontend): stop streamed deltas rendering twice and fragmenting in V1 chat by @shanemort1982 in https://github.com/OpenHands/OpenHands/pull/15108 +* fix: crash when request.client is None in InMemoryRateLimiter by @rakshith1928 in https://github.com/OpenHands/OpenHands/pull/15119 +* fix(sandbox-spec): fall back to defaults when runtime-api has no warm runtimes by @tofarr in https://github.com/OpenHands/OpenHands/pull/15141 +* fix: settings page scroll layout by @saurya in https://github.com/OpenHands/OpenHands/pull/15147 +* fix(app_server): pass flat mcp_config shape to SDK Agent by @tofarr in https://github.com/OpenHands/OpenHands/pull/15159 +* fix: scroll settings sidebar so Skills is reachable in orgs by @hieptl in https://github.com/OpenHands/OpenHands/pull/15138 +* fix(frontend): read SDK 1.31.x flat mcp_config wire format by @tofarr in https://github.com/OpenHands/OpenHands/pull/15165 +* fix(app_server): derive agent server image from package version by @tofarr in https://github.com/OpenHands/OpenHands/pull/15168 +* fix(app-server): pass index columns as a list in migration 013 by @VascoSch92 in https://github.com/OpenHands/OpenHands/pull/15176 +* fix: default ENABLE_ACP on so ACP agent settings show in OH Cloud by @hieptl in https://github.com/OpenHands/OpenHands/pull/15183 +* fix: send authenticated marketplace URLs to agent-server by @hieptl in https://github.com/OpenHands/OpenHands/pull/15187 +* fix: prevent webhook-driven DB connection leaks by @tofarr in https://github.com/OpenHands/OpenHands/pull/15212 +* fix(frontend): mention SMTP env vars for budget alerts by @saurya in https://github.com/OpenHands/OpenHands/pull/15218 +* fix(enterprise): cascade-delete conversation_cost_events on conversation delete by @tofarr in https://github.com/OpenHands/OpenHands/pull/15220 +* fix: Enable LIFO database connection pooling by @tofarr in https://github.com/OpenHands/OpenHands/pull/15225 +* fix(app-server): preserve observability context metadata by @hxaxd in https://github.com/OpenHands/OpenHands/pull/15215 +* fix(app-server): preserve conversation created_at across lifecycle webhooks by @Sujit-1509 in https://github.com/OpenHands/OpenHands/pull/15243 +* fix(mcp): preserve SaaS credentials with encrypted storage by @simonrosenberg in https://github.com/OpenHands/OpenHands/pull/15257 +* fix(frontend): restore cross-domain PostHog tracking by aligning client/server distinct_id (WIP) by @lilagrc in https://github.com/OpenHands/OpenHands/pull/15100 +* fix(app-server): lower DB pool defaults and make them env-tunable by @dylan-openhands in https://github.com/OpenHands/OpenHands/pull/15270 +* fix(mcp): preserve MCP auth secrets stripped by settings GET round-trip by @jlav in https://github.com/OpenHands/OpenHands/pull/15285 + +#### Maintenance +* build: pin dependency versions exactly by @rbren in https://github.com/OpenHands/OpenHands/pull/14384 +* ci: add release ready gate by @enyst in https://github.com/OpenHands/OpenHands/pull/14987 +* ci: PLTF-2960 open a chart image-tag bump PR on cloud release by @aivong-openhands in https://github.com/OpenHands/OpenHands/pull/15166 +* ci: PLTF-2960 sync chart appVersion with cloud image tag by @aivong-openhands in https://github.com/OpenHands/OpenHands/pull/15219 +* ci: wait for the docker build before retagging images by @jlav in https://github.com/OpenHands/OpenHands/pull/15213 +* chore: Update README.md by @rbren in https://github.com/OpenHands/OpenHands/pull/15271 + +--- + +### Software Agent SDK + +#### Features +* feat(agent-server): expose repository metadata for workspace archives by @simonrosenberg in https://github.com/OpenHands/software-agent-sdk/pull/3932 +* feat: commit-history API β€” list commits and per-commit diffs by @hieptl in https://github.com/OpenHands/software-agent-sdk/pull/4075 +* feat(security): add ToolShieldLLMSecurityAnalyzer by @xli04 in https://github.com/OpenHands/software-agent-sdk/pull/2911 + +#### Bug Fixes +* fix(skills): match keyword triggers on whole words only by @VascoSch92 in https://github.com/OpenHands/software-agent-sdk/pull/4008 +* fix(sdk): reconnect remote conversation websocket by @bozhnyukAlex in https://github.com/OpenHands/software-agent-sdk/pull/3987 +* fix(security): add a secret-disclosure consent rule to the agent security policy by @warmjademe in https://github.com/OpenHands/software-agent-sdk/pull/3823 +* fix(sdk): keep legacy history on resume when the stored tail is a non-tree artifact by @VascoSch92 in https://github.com/OpenHands/software-agent-sdk/pull/4068 +* fix: support GPT-5.6 across Codex authentication by @neubig in https://github.com/OpenHands/software-agent-sdk/pull/4056 +* fix: pick a display base ref that keeps committed work visible by @hieptl in https://github.com/OpenHands/software-agent-sdk/pull/4065 +* fix(mcp): validate secrets after parsing by @simonrosenberg in https://github.com/OpenHands/software-agent-sdk/pull/4099 +* fix(skills): make marketplaces additive to public skills by @rsd-darshan in https://github.com/OpenHands/software-agent-sdk/pull/4087 +* fix(mcp): preserve nested object properties in LLM-facing tool schema by @ixchio in https://github.com/OpenHands/software-agent-sdk/pull/4011 +* [codex] fix ACP prompt argument order by @neubig in https://github.com/OpenHands/software-agent-sdk/pull/3996 + +#### Maintenance +* ci(version-bump-prs): make PR-creation steps independent by @VascoSch92 in https://github.com/OpenHands/software-agent-sdk/pull/4051 +* ci: add release security-scan by @smolpaws in https://github.com/OpenHands/software-agent-sdk/pull/4042 +* chore(deps): bump MishaKav/pytest-coverage-comment from 1.7.2 to 1.10.0 by @dependabot[bot] in https://github.com/OpenHands/software-agent-sdk/pull/4046 +* chore(deps): bump docker/setup-buildx-action from 4.0.0 to 4.2.0 by @dependabot[bot] in https://github.com/OpenHands/software-agent-sdk/pull/4045 + +--- + +### Runtime API + +#### Features +* feat(logging): emit exc_info and stack_info as JSON arrays by @tofarr in https://github.com/OpenHands/runtime-api/pull/635 +* feat(cleanup): enrich final workspace archive manifests by @simonrosenberg in https://github.com/OpenHands/runtime-api/pull/630 + +#### Bug Fixes +* fix: prevent DetachedInstanceError on Runtime accessed after session close by @tofarr in https://github.com/OpenHands/runtime-api/pull/636 + +--- + +### OpenHands Cloud (Helm Chart) + +#### Features +* feat: upgrade embedded cluster to 2.19.2+k8s-1.34 by @jlav in https://github.com/OpenHands/OpenHands-Cloud/pull/821 +* feat: upgrade embedded cluster to 2.19.2+k8s-1.35 by @jlav in https://github.com/OpenHands/OpenHands-Cloud/pull/822 +* feat: upgrade embedded cluster to 2.19.2+k8s-1.36 by @jlav in https://github.com/OpenHands/OpenHands-Cloud/pull/826 +* feat(sysbox): default sandbox isolation on the embedded cluster by @jlav in https://github.com/OpenHands/OpenHands-Cloud/pull/770 +* feat: PLTF-3196 Configure global OpenHands resolver label by @aivong-openhands in https://github.com/OpenHands/OpenHands-Cloud/pull/807 +* feat: PLTF-2960 sync metadata with image tag bumps by @aivong-openhands in https://github.com/OpenHands/OpenHands-Cloud/pull/828 +* feat: Add replicated vendor portal links in release workflows by @dylan-openhands in https://github.com/OpenHands/OpenHands-Cloud/pull/833 +* feat: PLTF-3198 enable the Replicated SDK by default for helm installs by @aivong-openhands in https://github.com/OpenHands/OpenHands-Cloud/pull/895 +* feat(replicated): add OEM User Creation Flow advanced option by @jpshackelford in https://github.com/OpenHands/OpenHands-Cloud/pull/914 + +#### Bug Fixes +* fix(postgres): raise embedded postgres memory limit to avoid OOM by @jlav in https://github.com/OpenHands/OpenHands-Cloud/pull/829 +* fix: improve integrations-hub Datadog and probe configuration by @neubig in https://github.com/OpenHands/OpenHands-Cloud/pull/862 +* fix(openhands): stop warm-runtimes job pods matching the runtime-api Service selector by @ak684 in https://github.com/OpenHands/OpenHands-Cloud/pull/867 +* fix(openhands): mirror agentServerEnv into warm-runtime env so warm pools stay claimable by @ak684 in https://github.com/OpenHands/OpenHands-Cloud/pull/866 +* fix: set default agent-server tag back to 1.36.0-python by @jlav in https://github.com/OpenHands/OpenHands-Cloud/pull/908 + +#### Maintenance +* ci: PLTF-2920 dispatch staging chart bumps after publish by @aivong-openhands in https://github.com/OpenHands/OpenHands-Cloud/pull/801 +* refactor(openhands): rename gitlab webhook install cronjob by @jlav in https://github.com/OpenHands/OpenHands-Cloud/pull/865 +* ci: PLTF-3193 dispatch development chart bumps after publish by @aivong-openhands in https://github.com/OpenHands/OpenHands-Cloud/pull/843 +* test: PLTF-1257 helm-unittest setup by @aivong-openhands in https://github.com/OpenHands/OpenHands-Cloud/pull/894 +* chore: add CODEOWNERS by @jlav in https://github.com/OpenHands/OpenHands-Cloud/pull/878 + +### Skills and Plugins +Source: https://docs.openhands.dev/enterprise/skills-and-plugins.md + +OpenHands Enterprise supports several ways to add reusable guidance and capabilities to +conversations. Choose the approach that meets your needs. + + + This guide covers Enterprise distribution and governance. For skill formats, triggers, and + precedence, see [Skills](/overview/skills). For plugin structure and development, see + [Plugins](/overview/plugins). + + +## Choose a Distribution Method + +| Method | Scope | Use When | +|---|---|---| +| `AGENTS.md` | One repository | Instructions should apply whenever OpenHands works in the repository | +| `.agents/skills/` | One repository | A focused workflow or reference should load on demand | +| Organization skills repository | Organization | Standards should be available across the organization's conversations | +| User skills repository | One user | A skill should follow one user across conversations | +| Conversation plugin | One conversation | A capability bundle is needed for a specific task | +| Marketplace | User or organization | Users need a governed collection of plugins they can load on demand | +| Marketplace Auto-Load | User or organization | Every applicable conversation requires the marketplace's plugins | + +## Understand Enterprise Loading Layers + +Enterprise marketplaces operate at three different layers: + +1. **Instance Plugin Marketplace** β€” An administrator configures the catalog source through + Replicated or Helm. This powers the Plugin Directory at `/plugins`. +2. **Registered marketplace** β€” A user or organization registers a Git repository under + `Settings` > `Skills`. Registration makes its plugins discoverable and governable. +3. **Conversation attachment** β€” A plugin is loaded into a conversation through the Plugin + Directory, a launch link, the V1 API, or Auto-Load. + +Registering a marketplace does not by itself load every plugin into every conversation. + +## Add Repository Skills + +Use repository files when a skill or instruction belongs to one codebase. + +### Permanent Repository Context + +Add `AGENTS.md` at the repository root for concise instructions that should always apply: + +```text +my-project/ +└── AGENTS.md +``` + +OpenHands loads this file when a conversation uses the repository. + +### On-Demand Repository Skills + +Add one directory per skill under `.agents/skills/`: + +```text +my-project/ +└── .agents/ + └── skills/ + └── deploy-helper/ + β”œβ”€β”€ SKILL.md + β”œβ”€β”€ scripts/ + └── references/ +``` + +The `SKILL.md` file contains the skill name, description, and instructions. OpenHands initially +shows the agent a summary and loads the full content when the skill is invoked or triggered. + +See [Skills](/overview/skills) for the complete format and loading precedence. + +## Add Organization and User Skills + +Use a special configuration repository when skills should apply beyond one project. + +For GitHub, create a repository named `.agents` under the organization or user and place skills +under `skills/`: + +```text +Great-Co/.agents +└── skills/ + └── engineering-standards/ + └── SKILL.md +``` + +For GitLab organizations, use `openhands-config` because GitLab repository names cannot begin +with a period. + + + Earlier OpenHands Enterprise releases may use a `.openhands` configuration repository. If an + existing deployment already uses `.openhands`, confirm the supported convention for that + release before migrating. Do not define duplicate skill names in both repositories. + + +The source control integration must have access to the configuration repository. Access to one +user or organization does not grant access to repositories owned by another organization. + +See [Organization and User Skills](/overview/skills/org) for more information. + +## Register a Marketplace + +Register a marketplace to make a Git-hosted plugin collection available to a user or organization. + +1. Open `Settings` > `Skills`. +2. In `Marketplaces`, select `+ Add Repository`. +3. Enter the repository URL. +4. Optionally specify a branch, tag, commit, or repository path. +5. Select the personal or organization scope available to your role. +6. Save the marketplace. + +The `Skills & Plugins` table shows the entries discovered from registered marketplaces and +built-in sources. + + + Register only repositories you trust. A loaded plugin can include skills, hooks, MCP servers, + agents, and commands. It can also use secrets available to the conversation. Explicit launch + flows require trust confirmation. Review every plugin before enabling Auto-Load, which may + attach plugins without a per-conversation prompt. + + +For private repositories, ensure that your Enterprise source control integration has access. + +## Load a Plugin for One Conversation + +Use explicit attachment when a plugin is needed for one task. This keeps ordinary conversations +isolated from unrelated plugin context and integrations. + + + + 1. Open `https://app./plugins`. + 2. Select a plugin. + 3. Select `Create New Conversation`. + 4. Review the repository, path, and ref. + 5. Confirm that you trust the plugin. + 6. Select `Start Conversation`. + + The plugin is loaded only into the new conversation. + + + Use the `/launch` route to share a preconfigured plugin: + + ```text + https://app./launch?plugins= + ``` + + A launch link can include multiple plugins, editable parameter defaults, and an optional + starting message. The user reviews the configuration and confirms trust before the + conversation starts. + + See [Plugin Launcher](/openhands/usage/cloud/plugin-launcher) for the plugin definition and + encoding format. Replace the Cloud hostname in its examples with your Enterprise application + hostname. + + + Add a `plugins` array to `POST /api/v1/app-conversations`: + + ```json + { + "initial_message": { + "content": [ + { + "type": "text", + "text": "Run the release readiness check." + } + ] + }, + "plugins": [ + { + "source": "github:AcmeCo/openhands-plugins", + "ref": "main", + "repo_path": "plugins/release-ready" + } + ] + } + ``` + + See [Cloud API](/openhands/usage/cloud/cloud-api) for authentication, response handling, and + conversation status. Use your Enterprise application hostname as the base URL. + + + +## Configure Auto-Load + +Auto-Load adds a registered marketplace's plugins to every applicable conversation in its scope. + +Use Auto-Load when: + +- Every conversation requires the capability. +- The marketplace is controlled and reviewed by your organization. +- The additional context and startup work are acceptable. +- The plugins are allowed to use the secrets available in those conversations. + +Keep Auto-Load off when users should choose plugins per task. + +To change Auto-Load: + +1. Open `Settings` > `Skills`. +2. Find the marketplace under `Marketplaces`. +3. Toggle `Auto-Load`. +4. Save the changes. +5. Start a new conversation to verify the new behavior. + +Changes do not retroactively reload skills or plugins in an already-running conversation. + +## Verify Skill and Plugin Loading + +Use this to really verify loading instead of checking only that a name appears in the UI. + +1. Create a small skill with a unique trigger and an exact expected response. +2. Start a new conversation in the intended scope. +3. Use the trigger. +4. Confirm that the response reflects the skill's instructions. +5. Start a control conversation outside that scope and confirm that the skill does not activate. + +For organization skills, use a conversation without a selected repository or explicit plugin when +the release supports organization-wide loading in that context. For marketplace Auto-Load, compare +a conversation created before the setting changed with a new conversation created afterward. + +## Troubleshooting + + + + Registration makes plugins available on demand. Enable Auto-Load for the marketplace or attach + a plugin explicitly through the Plugin Directory, a launch link, or the V1 API. + + + Confirm that the conversation selected the expected repository and ref. Verify the skill path + is `.agents/skills//SKILL.md` and that the source control integration can clone the + repository. + + + Confirm that its trigger matches the user message or explicitly ask the agent to invoke the + skill. Test with a unique trigger and exact expected behavior. + + + +## Next Steps + + + + Learn about skill formats, triggers, and loading precedence. + + + Build bundles containing skills, hooks, MCP servers, agents, and commands. + + + Enable and configure the Enterprise Plugin Directory. + + + Create shareable links that open conversations with plugins attached. + + diff --git a/llms.txt b/llms.txt index 18f3f35b..9357db69 100644 --- a/llms.txt +++ b/llms.txt @@ -71,6 +71,7 @@ from the OpenHands Software Agent SDK. - [Parallel Tool Execution](https://docs.openhands.dev/sdk/guides/parallel-tool-execution.md): Execute multiple tools concurrently within a single LLM response to improve throughput for independent operations. - [Pause and Resume](https://docs.openhands.dev/sdk/guides/convo-pause-and-resume.md): Pause agent execution, perform operations, and resume without losing state. - [Persistence](https://docs.openhands.dev/sdk/guides/convo-persistence.md): Save and restore conversation state for multi-session workflows. +- [Persistent Memory](https://docs.openhands.dev/sdk/guides/persistent-memory.md): Give agents opt-in, two-tier memory that survives across conversations. - [Plugins](https://docs.openhands.dev/sdk/guides/plugins.md): Plugins bundle skills, hooks, MCP servers, agents, and commands into reusable packages that extend agent capabilities. - [PR Review](https://docs.openhands.dev/sdk/guides/github-workflows/pr-review.md): Use OpenHands Agent to generate meaningful pull request review - [Reasoning](https://docs.openhands.dev/sdk/guides/llm-reasoning.md): Access model reasoning traces from Anthropic extended thinking and OpenAI responses API. @@ -235,18 +236,23 @@ from the OpenHands Software Agent SDK. ## Other +- [Amazon EKS](https://docs.openhands.dev/enterprise/k8s-install/eks.md): Prepare an Amazon EKS cluster to run OpenHands Enterprise - [Analytics](https://docs.openhands.dev/enterprise/analytics.md): Deploy Laminar for trace analysis in OpenHands Enterprise. - [Azure DevOps](https://docs.openhands.dev/enterprise/integrations/azure-devops.md): Configure Azure DevOps authentication and automation triggers for OpenHands Enterprise. - [Bitbucket Data Center](https://docs.openhands.dev/enterprise/integrations/bitbucket-data-center.md): Configure Bitbucket Data Center authentication and repository webhooks for OpenHands Enterprise. - [Custom Sandbox Images](https://docs.openhands.dev/enterprise/custom-sandbox-image.md): Preload repos, dependencies, and tooling into a custom sandbox image to make your agents faster and more reliable. +- [DNS and TLS](https://docs.openhands.dev/enterprise/k8s-install/dns-and-tls.md): Automate DNS records and TLS certificates with external-dns and cert-manager - [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 - [Install with Helm](https://docs.openhands.dev/enterprise/k8s-install/installation.md): End-to-end installation of OpenHands Enterprise on Kubernetes using Helm +- [Installing Sysbox](https://docs.openhands.dev/enterprise/k8s-install/sysbox.md): Install the Sysbox runtime so agent sandboxes can run securely - [Jira Data Center](https://docs.openhands.dev/enterprise/integrations/jira-data-center.md): Configure Jira Data Center for OpenHands Enterprise. - [Kubernetes Installation](https://docs.openhands.dev/enterprise/k8s-install.md): Deploy OpenHands Enterprise into your own Kubernetes cluster using Helm - [OpenHands Enterprise](https://docs.openhands.dev/enterprise.md): Run AI coding agents on your own infrastructure with complete control - [Plugin Marketplace](https://docs.openhands.dev/enterprise/plugin-marketplace.md): Enable and configure the Plugin Marketplace to browse and install community-built OpenHands plugins. - [Quick Start](https://docs.openhands.dev/enterprise/quick-start.md): Get started with a 30-day trial of OpenHands Enterprise. +- [Release Notes](https://docs.openhands.dev/enterprise/release-notes.md): Release notes for OpenHands Enterprise - [Resource Limits](https://docs.openhands.dev/enterprise/k8s-install/resource-limits.md): Configure memory, CPU, and storage for OpenHands Enterprise components - [Running Docker in the Agent Sandbox](https://docs.openhands.dev/enterprise/docker-in-sandbox.md): Let agents run containers, Docker Compose, and image builds inside their isolated sandboxβ€”safely, without privileged access to your cluster. +- [Skills and Plugins](https://docs.openhands.dev/enterprise/skills-and-plugins.md): Manage repository, organization, and user skills and control how plugins are discovered and loaded in OpenHands Enterprise. - [Slack](https://docs.openhands.dev/enterprise/integrations/slack.md): Configure the Slack integration for a self-hosted OpenHands Enterprise install.