From cc2800b042d95f0f9821b21b208a85eb09a1f157 Mon Sep 17 00:00:00 2001 From: "warp-agent-staging[bot]" <240773466+warp-agent-staging[bot]@users.noreply.github.com> Date: Sun, 20 Sep 2026 17:29:10 +0000 Subject: [PATCH 1/4] docs: add external orchestrator deployment example Co-Authored-By: Oz --- .../self-hosting/external-orchestrators.mdx | 113 ++++++++++++++++++ .../platform/self-hosting/managed-direct.mdx | 1 + .../docs/platform/self-hosting/reference.mdx | 37 +++++- .../docs/platform/self-hosting/unmanaged.mdx | 1 + src/sidebar.ts | 1 + 5 files changed, 147 insertions(+), 6 deletions(-) create mode 100644 src/content/docs/platform/self-hosting/external-orchestrators.mdx diff --git a/src/content/docs/platform/self-hosting/external-orchestrators.mdx b/src/content/docs/platform/self-hosting/external-orchestrators.mdx new file mode 100644 index 000000000..1741a672a --- /dev/null +++ b/src/content/docs/platform/self-hosting/external-orchestrators.mdx @@ -0,0 +1,113 @@ +--- +title: Running agents with an external orchestrator +description: >- + Connect an external job scheduler to self-hosted agents with a one-shot Direct worker + or the Command backend. +--- +import { VARS } from '@data/vars'; + +Use an existing CI system, Kubernetes controller, or internal scheduler to allocate compute while the {VARS.WARP_AUTOMATION_PLATFORM} routes and tracks each run. The worker supports two patterns for this setup: start a one-shot Direct worker for each job, or use a long-lived Command worker that delegates runs to your runtime. + +## Choosing an orchestration pattern + +Both patterns keep execution on your infrastructure and require outbound connectivity to Warp. + +| Pattern | External orchestrator responsibility | Worker behavior | Use when | +| --- | --- | --- | --- | +| **One-shot Direct worker** | Starts a worker process and creates a run for its unique worker ID | Runs one task on the allocated host, then exits | Your scheduler allocates a VM, pod, or CI runner for each job | +| **Command backend** | Exposes an API or command that can accept a task payload and start the agent | Stays connected and invokes your dispatch command for each task | Your runtime already has its own job API, queue, or compute lifecycle | + +One-shot mode works only with the Direct backend. It forces `max_concurrent_tasks` to `1` and waits for one accepted task to finish, fail, or be cancelled before the worker exits. If no task arrives, the worker stays connected until your orchestrator stops it. + +The Command backend is fire-and-forget. The dispatch command returns after the external runtime durably accepts the task. The remote agent, not the worker process, reports progress and completion to Warp. + +## Running a one-shot Direct worker + +This example starts a worker and routes one cloud agent run to it from the same job. Use a unique worker ID so another worker cannot claim the run. + +### Prerequisites + +* **Self-hosting enabled for your Enterprise team** - [Contact sales](https://www.warp.dev/contact-sales) if self-hosting is not enabled. +* **The worker and CLI binaries** - Install `oz-agent-worker` from a [published release](https://github.com/warpdotdev/oz-agent-worker/releases) and install the {VARS.WARP_AGENT_CLI} by following the [CLI installation instructions](/reference/cli/#installing-the-cli). +* **An agent API key** - Create one in the {VARS.WEB_APP}. Store it in your orchestrator's secret manager as `WARP_API_KEY`. + +### Start and route the run + +Add the following script to the job your orchestrator starts. Replace `CI_JOB_ID` with a unique job identifier from your system. + +```bash title="run-agent.sh" +#!/usr/bin/env bash +set -euo pipefail + +: "${WARP_API_KEY:?Set WARP_API_KEY in the job environment}" +: "${CI_JOB_ID:?Set CI_JOB_ID to a unique job identifier}" + +worker_id="external-${CI_JOB_ID}" + +oz-agent-worker \ + --worker-id "$worker_id" \ + --backend direct \ + --one-shot & +worker_pid=$! + +trap 'kill "$worker_pid" 2>/dev/null || true' EXIT + +oz agent run-cloud \ + --host "$worker_id" \ + --prompt "Run the test suite, fix failures, and open a pull request." + +wait "$worker_pid" +trap - EXIT +``` + +The run may enter the queue before the worker finishes connecting. Warp assigns it after the matching worker ID is online. The job exits when the agent reaches a terminal state and the one-shot worker shuts down. + +Use Direct backend [setup and teardown commands](/platform/self-hosting/managed-direct/#setup-and-teardown-commands) to prepare the workspace on the allocated host. + +## Delegating runs with the Command backend + +Use the Command backend when the external runtime owns job creation and cleanup. The worker invokes `dispatch_command` once for each assigned task and writes a versioned JSON payload to standard input. + +The payload includes: + +* `base_args` - The `oz agent run` argument vector for the external runtime. +* `docker_image` and `sidecars` - The task image and required sidecar mounts. +* `env` - Task environment variables and credentials. Keep this payload out of logs. +* `run_id` and `server_root_url` - Values the agent uses to report status to Warp. + +The public [`command-backend` example](https://github.com/warpdotdev/oz-agent-worker/tree/main/examples/command-backend) includes dependency-free Python dispatch and cancellation scripts for an HTTP runtime. Copy those scripts to the worker host, then configure the worker: + +```yaml title="worker.yaml" +worker_id: "external-runtime" +backend: + command: + dispatch_command: "python3 /opt/warp/dispatch.py" + cancel_command: "python3 /opt/warp/cancel.py" + dispatch_timeout: "60s" + environment: + - name: OZ_DISPATCH_URL + value: "https://runtime.internal.example.com/agent-runs" + - name: OZ_CANCEL_URL + value: "https://runtime.internal.example.com/agent-runs/cancel" + - name: OZ_DISPATCH_AUTH_HEADER +``` + +Start the worker with the authentication header and Warp API key supplied by your secret manager: + +```bash +export OZ_DISPATCH_AUTH_HEADER="Bearer YOUR_RUNTIME_TOKEN" +export WARP_API_KEY="YOUR_AGENT_API_KEY" + +oz-agent-worker --config-file worker.yaml +``` + +Adapt the example script's `transform()` function to your runtime's request schema. Your runtime must launch `base_args` with the supplied task environment, image, and sidecars. After the CLI exits, it must run `oz harness-support --run-id RUN_ID report-shutdown` so Warp receives the terminal state. + +An exit code of `0` from `dispatch_command` means the external runtime accepted responsibility for the task. A nonzero exit or a dispatch timeout fails the task. `max_concurrent_tasks` limits simultaneous dispatch calls, not the number of agents running in the external runtime. + +## Related pages + +* [Managed: Direct backend](/platform/self-hosting/managed-direct/) - Run agent tasks directly on a worker host. +* [Unmanaged architecture](/platform/self-hosting/unmanaged/) - Invoke `oz agent run` directly when Warp does not need to route the run. +* [Self-hosted worker reference](/platform/self-hosting/reference/) - Look up worker flags and backend configuration fields. +* [Routing runs to self-hosted workers](/platform/self-hosting/#routing-runs-to-self-hosted-workers) - Route runs from the CLI, API, schedules, integrations, or the web app. diff --git a/src/content/docs/platform/self-hosting/managed-direct.mdx b/src/content/docs/platform/self-hosting/managed-direct.mdx index 555c668c0..63d38d100 100644 --- a/src/content/docs/platform/self-hosting/managed-direct.mdx +++ b/src/content/docs/platform/self-hosting/managed-direct.mdx @@ -126,6 +126,7 @@ backend: ## Related pages * [Self-hosted worker reference](/platform/self-hosting/reference/#direct-backend-config) — Full config schema for the Direct backend. +* [External orchestrators](/platform/self-hosting/external-orchestrators/) — Start one Direct worker per external job or delegate runs through the Command backend. * [Self-hosting overview](/platform/self-hosting/) — Managed vs unmanaged and the backend decision guide. * [Routing runs to self-hosted workers](/platform/self-hosting/#routing-runs-to-self-hosted-workers) — How to send tasks to your connected worker from the CLI, schedules, integrations, the API, and the web UI. * [Security and networking](/platform/self-hosting/security-and-networking/) — Data boundaries and security considerations for the Direct backend. diff --git a/src/content/docs/platform/self-hosting/reference.mdx b/src/content/docs/platform/self-hosting/reference.mdx index c5ced7a2d..8e44fa7e5 100644 --- a/src/content/docs/platform/self-hosting/reference.mdx +++ b/src/content/docs/platform/self-hosting/reference.mdx @@ -2,13 +2,13 @@ title: Self-hosted worker reference description: >- Complete reference for the oz-agent-worker daemon — CLI flags and config - file schema for the Docker, Kubernetes, and Direct backends. + file schema for the Docker, Kubernetes, Direct, and Command backends. --- -Reference for the `oz-agent-worker` daemon: CLI flags and the full YAML config-file schema for all three [managed backends](/platform/self-hosting/#managed-architecture) — Docker, Kubernetes, and Direct. For installation instructions, see [Install and run the worker](/platform/self-hosting/managed-docker/#install-and-run-the-worker). +Reference for the `oz-agent-worker` daemon: CLI flags and the full YAML config-file schema for the Docker, Kubernetes, Direct, and Command backends. For installation instructions, see [Install and run the worker](/platform/self-hosting/managed-docker/#install-and-run-the-worker). :::note -This page documents every flag and config option. For installation and backend-specific setup walkthroughs, see [Managed: Docker](/platform/self-hosting/managed-docker/), [Managed: Kubernetes](/platform/self-hosting/managed-kubernetes/), or [Managed: Direct](/platform/self-hosting/managed-direct/). This reference applies to the managed architecture only; the [unmanaged architecture](/platform/self-hosting/unmanaged/) uses `oz agent run` instead. +This page documents every flag and config option. For installation and backend-specific setup walkthroughs, see [Managed: Docker](/platform/self-hosting/managed-docker/), [Managed: Kubernetes](/platform/self-hosting/managed-kubernetes/), [Managed: Direct](/platform/self-hosting/managed-direct/), or [External orchestrators](/platform/self-hosting/external-orchestrators/). This reference applies to the managed architecture only; the [unmanaged architecture](/platform/self-hosting/unmanaged/) uses `oz agent run` instead. ::: --- @@ -25,12 +25,13 @@ The following flags are available when starting the worker. ### Optional * `--config-file` — Path to a YAML [config file](#config-file). CLI flags take precedence over config file values. -* `--backend` — Backend type: `docker` (default), `kubernetes`, or `direct`. See [Managed: Kubernetes](/platform/self-hosting/managed-kubernetes/) and [Managed: Direct](/platform/self-hosting/managed-direct/) for backend-specific setup. +* `--backend` — Backend type: `docker` (default), `kubernetes`, `direct`, or `command`. See [Managed: Kubernetes](/platform/self-hosting/managed-kubernetes/), [Managed: Direct](/platform/self-hosting/managed-direct/), and [External orchestrators](/platform/self-hosting/external-orchestrators/) for backend-specific setup. * `--log-level` — Log verbosity. One of `debug`, `info`, `warn`, `error`. Defaults to `info`. * `--no-cleanup` — Keep task containers, Kubernetes Jobs, or workspace directories after execution instead of removing them. Useful for debugging failed tasks. * `-v` / `--volumes` — Mount host directories into task containers (Docker backend only). Format: `HOST_PATH:CONTAINER_PATH` or `HOST_PATH:CONTAINER_PATH:MODE` (where MODE is `ro` or `rw`). Can be specified multiple times. * `-e` / `--env` — Set environment variables for tasks. Format: `KEY=VALUE` (explicit value) or `KEY` (pass through from host environment). Can be specified multiple times. * `--max-concurrent-tasks` — Maximum number of tasks to run concurrently. Defaults to `0` (unlimited). When set, additional tasks wait until a slot is available. +* `--one-shot` — Exit after one accepted task succeeds, fails, or is cancelled. Supported only by the Direct backend and forces `max_concurrent_tasks` to `1`. * `--idle-on-complete` — How long to keep the `oz` process alive after a task's conversation finishes, allowing follow-up interactions via session sharing. Uses duration format (e.g. `45m`, `10m`, `0s`). Defaults to `45m` when not set. Set to `0s` to disable. :::note @@ -130,6 +131,21 @@ backend: value: "hello" ``` +### Command backend config + +```yaml +worker_id: "command-worker" +backend: + command: + dispatch_command: "python3 /opt/warp/dispatch.py" + cancel_command: "python3 /opt/warp/cancel.py" + dispatch_timeout: "60s" + environment: + - name: OZ_DISPATCH_URL + value: "https://runtime.internal.example.com/agent-runs" + - name: OZ_DISPATCH_AUTH_HEADER +``` + ### Config file fields **Top-level:** @@ -137,8 +153,9 @@ backend: * `worker_id` — Worker identifier (same as `--worker-id` flag). * `cleanup` — Whether to clean up after tasks. Defaults to `true`. Set to `false` to keep containers/workspaces for debugging (equivalent to `--no-cleanup`). * `max_concurrent_tasks` — Maximum concurrent tasks. Defaults to unlimited. +* `one_shot` — Exit after one accepted Direct backend task reaches a terminal state. Defaults to `false` and forces `max_concurrent_tasks` to `1` when enabled. * `idle_on_complete` — Duration to keep the `oz` process alive after task completion (e.g. `"45m"`, `"0s"`). -* `backend` — Backend configuration block. Only one backend (`docker`, `kubernetes`, or `direct`) may be specified. +* `backend` — Backend configuration block. Only one backend (`docker`, `kubernetes`, `direct`, or `command`) may be specified. **`backend.docker`:** @@ -169,8 +186,15 @@ backend: * `teardown_command` — Shell command to run after each task completes. * `environment` — List of environment variables (same format as the Docker backend). +**`backend.command`:** + +* `dispatch_command` — Required shell command that accepts a JSON task payload on standard input and hands the task to an external runtime. +* `cancel_command` — Optional shell command invoked when a dispatched task is cancelled. +* `dispatch_timeout` — Maximum runtime for the dispatch command. Defaults to `60s`. +* `environment` — Environment variables for the dispatch and cancellation commands. Task credentials remain in the standard-input payload. + :::note -Only one backend can be configured at a time. Specifying more than one of `docker`, `kubernetes`, and `direct` in the same config file is an error. +Only one backend can be configured at a time. Specifying more than one of `docker`, `kubernetes`, `direct`, and `command` in the same config file is an error. ::: --- @@ -200,6 +224,7 @@ Once a worker is running, route cloud agent runs to it with the `--host` flag or * [Managed: Docker](/platform/self-hosting/managed-docker/) — Docker backend setup, connectivity, and private registries. * [Managed: Kubernetes](/platform/self-hosting/managed-kubernetes/) — Kubernetes backend setup, Helm chart, pod template, and operational notes. * [Managed: Direct](/platform/self-hosting/managed-direct/) — Direct backend setup and workspace model. +* [External orchestrators](/platform/self-hosting/external-orchestrators/) — One-shot Direct workers and Command backend dispatch. * [Self-hosting overview](/platform/self-hosting/) — Architecture, decision guide, and Enterprise requirements. * [Environments](/platform/environments/) — Define the Docker image, repos, and setup commands used by task containers. * [Monitoring](/platform/self-hosting/monitoring/) — OpenTelemetry metrics for worker health, task throughput, and capacity. diff --git a/src/content/docs/platform/self-hosting/unmanaged.mdx b/src/content/docs/platform/self-hosting/unmanaged.mdx index 49cf1d397..960b70367 100644 --- a/src/content/docs/platform/self-hosting/unmanaged.mdx +++ b/src/content/docs/platform/self-hosting/unmanaged.mdx @@ -134,6 +134,7 @@ Unmanaged runs don't ship with the bundled declarations script, so end-of-run wo ## Related pages * [Self-hosting overview](/platform/self-hosting/) — Compare managed and unmanaged, plus the architecture decision guide. +* [External orchestrators](/platform/self-hosting/external-orchestrators/) — Compare one-shot Direct workers with the Command backend for externally allocated compute. * [GitHub Actions integration](/platform/integrations/github-actions/) — Run agents in CI with the official action. * [Deployment patterns](/platform/deployment-patterns/) — Pattern 1 (CLI-only) explains the unmanaged model conceptually. * [{VARS.WARP_AGENT_CLI}](/reference/cli/) — Full CLI reference for `oz agent run` and related commands. diff --git a/src/sidebar.ts b/src/sidebar.ts index 5115ad6ef..71c56a495 100644 --- a/src/sidebar.ts +++ b/src/sidebar.ts @@ -659,6 +659,7 @@ export const sidebarTopics: StarlightSidebarTopicsUserConfig = [ { slug: 'platform/self-hosting/managed-kubernetes', label: 'Managed: Kubernetes' }, { slug: 'platform/self-hosting/managed-direct', label: 'Managed: Direct' }, { slug: 'platform/self-hosting/unmanaged', label: 'Unmanaged' }, + { slug: 'platform/self-hosting/external-orchestrators', label: 'External orchestrators' }, 'platform/self-hosting/monitoring', { slug: 'platform/self-hosting/reference', label: 'Self-hosted worker reference' }, 'platform/self-hosting/security-and-networking', From c44f8eaecc99ae435bd2fa2364663584d78752f9 Mon Sep 17 00:00:00 2001 From: "warp-agent-staging[bot]" <240773466+warp-agent-staging[bot]@users.noreply.github.com> Date: Sun, 20 Sep 2026 17:52:25 +0000 Subject: [PATCH 2/4] docs: correct one-shot worker lifecycle Co-Authored-By: Oz --- .../platform/self-hosting/external-orchestrators.mdx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/content/docs/platform/self-hosting/external-orchestrators.mdx b/src/content/docs/platform/self-hosting/external-orchestrators.mdx index 1741a672a..c715b195c 100644 --- a/src/content/docs/platform/self-hosting/external-orchestrators.mdx +++ b/src/content/docs/platform/self-hosting/external-orchestrators.mdx @@ -17,7 +17,7 @@ Both patterns keep execution on your infrastructure and require outbound connect | **One-shot Direct worker** | Starts a worker process and creates a run for its unique worker ID | Runs one task on the allocated host, then exits | Your scheduler allocates a VM, pod, or CI runner for each job | | **Command backend** | Exposes an API or command that can accept a task payload and start the agent | Stays connected and invokes your dispatch command for each task | Your runtime already has its own job API, queue, or compute lifecycle | -One-shot mode works only with the Direct backend. It forces `max_concurrent_tasks` to `1` and waits for one accepted task to finish, fail, or be cancelled before the worker exits. If no task arrives, the worker stays connected until your orchestrator stops it. +One-shot mode works only with the Direct backend. It forces `max_concurrent_tasks` to `1` and waits for one accepted task's `oz` CLI process to exit before the worker exits. If no task arrives, the worker stays connected until your orchestrator stops it. The Command backend is fire-and-forget. The dispatch command returns after the external runtime durably accepts the task. The remote agent, not the worker process, reports progress and completion to Warp. @@ -25,6 +25,8 @@ The Command backend is fire-and-forget. The dispatch command returns after the e This example starts a worker and routes one cloud agent run to it from the same job. Use a unique worker ID so another worker cannot claim the run. +By default, the CLI stays open for 45 minutes after a conversation completes so users can send follow-up prompts. The example sets `--idle-on-complete 0s` so the CLI and worker exit without that idle period. A task-level `config.idle_timeout_minutes` value takes precedence, so leave it unset or set it to `0` for these tasks. + ### Prerequisites * **Self-hosting enabled for your Enterprise team** - [Contact sales](https://www.warp.dev/contact-sales) if self-hosting is not enabled. @@ -47,7 +49,8 @@ worker_id="external-${CI_JOB_ID}" oz-agent-worker \ --worker-id "$worker_id" \ --backend direct \ - --one-shot & + --one-shot \ + --idle-on-complete 0s & worker_pid=$! trap 'kill "$worker_pid" 2>/dev/null || true' EXIT @@ -60,7 +63,7 @@ wait "$worker_pid" trap - EXIT ``` -The run may enter the queue before the worker finishes connecting. Warp assigns it after the matching worker ID is online. The job exits when the agent reaches a terminal state and the one-shot worker shuts down. +The run may enter the queue before the worker finishes connecting. Warp assigns it after the matching worker ID is online. After the conversation completes, the `oz` CLI exits, then the one-shot worker and job exit. Use Direct backend [setup and teardown commands](/platform/self-hosting/managed-direct/#setup-and-teardown-commands) to prepare the workspace on the allocated host. From 234983716657a298890be8c2887188fb6ecbd73c Mon Sep 17 00:00:00 2001 From: "warp-agent-staging[bot]" <240773466+warp-agent-staging[bot]@users.noreply.github.com> Date: Mon, 21 Sep 2026 16:53:24 +0000 Subject: [PATCH 3/4] Refine external orchestrator terminology Co-Authored-By: Oz --- .../self-hosting/external-orchestrators.mdx | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/content/docs/platform/self-hosting/external-orchestrators.mdx b/src/content/docs/platform/self-hosting/external-orchestrators.mdx index c715b195c..88eaeaae5 100644 --- a/src/content/docs/platform/self-hosting/external-orchestrators.mdx +++ b/src/content/docs/platform/self-hosting/external-orchestrators.mdx @@ -1,12 +1,12 @@ --- title: Running agents with an external orchestrator description: >- - Connect an external job scheduler to self-hosted agents with a one-shot Direct worker - or the Command backend. + Connect an external job scheduler to self-hosted agents with the Direct backend + in one-shot mode or the Command backend. --- import { VARS } from '@data/vars'; -Use an existing CI system, Kubernetes controller, or internal scheduler to allocate compute while the {VARS.WARP_AUTOMATION_PLATFORM} routes and tracks each run. The worker supports two patterns for this setup: start a one-shot Direct worker for each job, or use a long-lived Command worker that delegates runs to your runtime. +Use an existing CI system, Kubernetes controller, or internal scheduler to allocate compute while the {VARS.WARP_AUTOMATION_PLATFORM} routes and tracks each run. The worker supports two patterns for this setup: start a Direct worker with `--one-shot` for each job, or use the Command backend to delegate runs to your runtime. ## Choosing an orchestration pattern @@ -14,14 +14,14 @@ Both patterns keep execution on your infrastructure and require outbound connect | Pattern | External orchestrator responsibility | Worker behavior | Use when | | --- | --- | --- | --- | -| **One-shot Direct worker** | Starts a worker process and creates a run for its unique worker ID | Runs one task on the allocated host, then exits | Your scheduler allocates a VM, pod, or CI runner for each job | +| **Direct backend** with `--one-shot` | Starts a worker process and creates a run for its unique worker ID | Runs one task on the allocated host, then exits | Your scheduler allocates a VM, pod, or CI runner for each job | | **Command backend** | Exposes an API or command that can accept a task payload and start the agent | Stays connected and invokes your dispatch command for each task | Your runtime already has its own job API, queue, or compute lifecycle | One-shot mode works only with the Direct backend. It forces `max_concurrent_tasks` to `1` and waits for one accepted task's `oz` CLI process to exit before the worker exits. If no task arrives, the worker stays connected until your orchestrator stops it. The Command backend is fire-and-forget. The dispatch command returns after the external runtime durably accepts the task. The remote agent, not the worker process, reports progress and completion to Warp. -## Running a one-shot Direct worker +## Running a Direct worker in one-shot mode This example starts a worker and routes one cloud agent run to it from the same job. Use a unique worker ID so another worker cannot claim the run. @@ -29,9 +29,9 @@ By default, the CLI stays open for 45 minutes after a conversation completes so ### Prerequisites -* **Self-hosting enabled for your Enterprise team** - [Contact sales](https://www.warp.dev/contact-sales) if self-hosting is not enabled. -* **The worker and CLI binaries** - Install `oz-agent-worker` from a [published release](https://github.com/warpdotdev/oz-agent-worker/releases) and install the {VARS.WARP_AGENT_CLI} by following the [CLI installation instructions](/reference/cli/#installing-the-cli). -* **An agent API key** - Create one in the {VARS.WEB_APP}. Store it in your orchestrator's secret manager as `WARP_API_KEY`. +* **Self-hosting enabled for your Enterprise team** — [Contact sales](https://www.warp.dev/contact-sales) if self-hosting is not enabled. +* **The worker and CLI binaries** — Install `oz-agent-worker` from a [published release](https://github.com/warpdotdev/oz-agent-worker/releases) and install the {VARS.WARP_AGENT_CLI} by following the [CLI installation instructions](/reference/cli/#installing-the-cli). +* **An agent API key** — Create one in the {VARS.WEB_APP}. Store it in your orchestrator's secret manager as `WARP_API_KEY`. ### Start and route the run @@ -73,10 +73,10 @@ Use the Command backend when the external runtime owns job creation and cleanup. The payload includes: -* `base_args` - The `oz agent run` argument vector for the external runtime. -* `docker_image` and `sidecars` - The task image and required sidecar mounts. -* `env` - Task environment variables and credentials. Keep this payload out of logs. -* `run_id` and `server_root_url` - Values the agent uses to report status to Warp. +* `base_args` — The `oz agent run` argument vector for the external runtime. +* `docker_image` and `sidecars` — The task image and required sidecar mounts. +* `env` — Task environment variables and credentials. Keep this payload out of logs. +* `run_id` and `server_root_url` — Values the agent uses to report status to Warp. The public [`command-backend` example](https://github.com/warpdotdev/oz-agent-worker/tree/main/examples/command-backend) includes dependency-free Python dispatch and cancellation scripts for an HTTP runtime. Copy those scripts to the worker host, then configure the worker: @@ -110,7 +110,7 @@ An exit code of `0` from `dispatch_command` means the external runtime accepted ## Related pages -* [Managed: Direct backend](/platform/self-hosting/managed-direct/) - Run agent tasks directly on a worker host. -* [Unmanaged architecture](/platform/self-hosting/unmanaged/) - Invoke `oz agent run` directly when Warp does not need to route the run. -* [Self-hosted worker reference](/platform/self-hosting/reference/) - Look up worker flags and backend configuration fields. -* [Routing runs to self-hosted workers](/platform/self-hosting/#routing-runs-to-self-hosted-workers) - Route runs from the CLI, API, schedules, integrations, or the web app. +* [Managed: Direct backend](/platform/self-hosting/managed-direct/) — Run agent tasks directly on a worker host. +* [Unmanaged architecture](/platform/self-hosting/unmanaged/) — Invoke `oz agent run` directly when Warp does not need to route the run. +* [Self-hosted worker reference](/platform/self-hosting/reference/) — Look up worker flags and backend configuration fields. +* [Routing runs to self-hosted workers](/platform/self-hosting/#routing-runs-to-self-hosted-workers) — Route runs from the CLI, API, schedules, integrations, or the web app. From 0957ad28208a57a37300b36ed78f814098f7b03a Mon Sep 17 00:00:00 2001 From: "warp-agent-staging[bot]" <240773466+warp-agent-staging[bot]@users.noreply.github.com> Date: Mon, 21 Sep 2026 17:12:31 +0000 Subject: [PATCH 4/4] Document all managed backends Co-Authored-By: Oz --- .../docs/platform/self-hosting/index.mdx | 48 +++++++++---------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/src/content/docs/platform/self-hosting/index.mdx b/src/content/docs/platform/self-hosting/index.mdx index baaa956c6..574cf24e1 100644 --- a/src/content/docs/platform/self-hosting/index.mdx +++ b/src/content/docs/platform/self-hosting/index.mdx @@ -20,7 +20,7 @@ Self-hosting lets your team run cloud agent workloads on your own infrastructure Self-hosting has two architectures. The core distinction is **who orchestrates agent runs** — not who owns the compute. Both models keep code and execution on your infrastructure. -* **Managed** — The {VARS.WARP_AUTOMATION_PLATFORM} orchestrates agent runs. You run the `oz-agent-worker` daemon on your infrastructure; it connects to the {VARS.WARP_AUTOMATION_PLATFORM} and waits for work. [Slack](/platform/integrations/slack/) mentions, Linear comments, [schedules](/platform/triggers/scheduled-agents/), API calls, and `oz agent run-cloud` commands all route tasks to your worker, which executes them in isolated Docker containers, Kubernetes Jobs, or directly on the host. Similar to a [GitHub self-hosted runner](https://docs.github.com/en/actions/hosting-your-own-runners). +* **Managed** — The {VARS.WARP_AUTOMATION_PLATFORM} orchestrates agent runs. You run `oz-agent-worker` on your infrastructure; it connects to the {VARS.WARP_AUTOMATION_PLATFORM} and waits for work. [Slack](/platform/integrations/slack/) mentions, Linear comments, [schedules](/platform/triggers/scheduled-agents/), API calls, and `oz agent run-cloud` commands route tasks to the worker. The Docker, Kubernetes, and Direct backends execute tasks on worker infrastructure. The Command backend dispatches tasks to an external runtime. Similar to a [GitHub self-hosted runner](https://docs.github.com/en/actions/hosting-your-own-runners). * **Unmanaged** — You orchestrate agent runs. You invoke `oz agent run` directly from your existing CI pipeline, Kubernetes pod, VM, or dev box. The {VARS.WARP_AUTOMATION_PLATFORM} provides session tracking and observability for each run, but does not start or stop agents for you. ### At a glance @@ -28,10 +28,10 @@ Self-hosting has two architectures. The core distinction is **who orchestrates a | Aspect | **Managed** | **Unmanaged** | | --- | --- | --- | | **Who triggers runs** | The {VARS.WARP_AUTOMATION_PLATFORM} (Slack, Linear, schedules, API, `run-cloud`) | Your system (CI, cron, scripts) | -| **What runs on your infra** | Long-lived `oz-agent-worker` daemon | One-shot `oz agent run` invocations | +| **What runs on your infra** | `oz-agent-worker`, either long-lived or started for one externally allocated job | One-shot `oz agent run` invocations | | **OS support** | Linux (macOS/Windows coming) | Linux, macOS, Windows | -| **Execution isolation** | Docker container, Kubernetes Job, or direct host | Whatever your host provides | -| **Automatic environment setup** | Yes (via Warp [environments](/platform/environments/)) | No (you manage it) | +| **Execution isolation** | Docker container, Kubernetes Job, direct host, or your external runtime | Whatever your host provides | +| **Automatic environment setup** | Docker, Kubernetes, and Direct: yes; Command: the external runtime applies the supplied task configuration | No (you manage it) | | **Session tracking and steering** | Yes | Yes | The two architectures are not mutually exclusive. Some teams run managed workers for integration-triggered work and unmanaged agents in CI pipelines. The deployment models diagram on [Deployment patterns](/platform/deployment-patterns/) compares what runs where in each model. @@ -69,45 +69,40 @@ Use these questions to decide between managed and unmanaged: 1. **Do you need agents to run on Windows or macOS?** * Yes → Use the [unmanaged](/platform/self-hosting/unmanaged/) architecture. Managed is Linux-only today. * No, Linux works → Continue to the next question. -2. **Do you want the {VARS.WARP_AUTOMATION_PLATFORM} to handle starting and stopping agents** (from Slack, the web interface, the Warp app, schedules, or the API)? - * Yes → Use the [managed](#managed-architecture) architecture. - * No, you have your own triggering mechanism → Use the [unmanaged](/platform/self-hosting/unmanaged/) architecture. -3. **Can your development environment run in a Docker container or Kubernetes pod?** - * Yes, Docker → [Managed: Docker](/platform/self-hosting/managed-docker/) backend. - * Yes, Kubernetes → [Managed: Kubernetes](/platform/self-hosting/managed-kubernetes/) backend. - * No (multi-service stacks that don't fit a single container, or environments where container runtimes aren't available) → [Unmanaged](/platform/self-hosting/unmanaged/) or [Managed: Direct](/platform/self-hosting/managed-direct/). -4. **Do you have your own orchestrator** (CI/CD, Kubernetes, internal job scheduler) **that starts agents on demand?** - * Yes → [Unmanaged](/platform/self-hosting/unmanaged/), using `oz agent run` as a drop-in. - * No → [Managed](#managed-architecture). +2. **How should runs start?** + * The {VARS.WARP_AUTOMATION_PLATFORM} should route each run to a worker that manages execution → Use the [managed](#managed-architecture) architecture, then choose a backend below. + * The {VARS.WARP_AUTOMATION_PLATFORM}, with your existing scheduler or runtime owning the compute lifecycle → Use a [managed external-orchestrator pattern](/platform/self-hosting/external-orchestrators/). + * Your system, by invoking `oz agent run` directly → Use the [unmanaged](/platform/self-hosting/unmanaged/) architecture. ### Choosing a managed backend -The managed architecture supports three backends for task execution: +The managed architecture supports four backends for task handling. Docker, Kubernetes, and Direct execute tasks on worker infrastructure. Command dispatches tasks to an external runtime. -1. **Are you deploying the worker into a Kubernetes cluster?** +1. **Should a long-lived worker hand each task to an existing job API, queue, or runtime?** + * Yes → Use the [Command backend](/platform/self-hosting/external-orchestrators/#delegating-runs-with-the-command-backend). + * No → Continue. +2. **Does an external scheduler start a dedicated worker process for each job?** + * Yes → Use the [Direct backend in one-shot mode](/platform/self-hosting/external-orchestrators/#running-a-direct-worker-in-one-shot-mode). + * No → Continue. +3. **Are you deploying the worker into a Kubernetes cluster?** * Yes → Use the [Kubernetes backend](/platform/self-hosting/managed-kubernetes/). Each task runs as a Kubernetes Job in your cluster; install with the included Helm chart. * No → Continue. -2. **Is Docker available on your worker host?** +4. **Is Docker available on your worker host?** * Yes → Use the [Docker backend](/platform/self-hosting/managed-docker/) (default). Tasks run in isolated containers. * No → Use the [Direct backend](/platform/self-hosting/managed-direct/). Tasks run directly on the host. -3. **Do you need container-level isolation between tasks?** - * Yes → [Docker](/platform/self-hosting/managed-docker/) or [Kubernetes](/platform/self-hosting/managed-kubernetes/) backend. - * No → Any backend works. -4. **Do you need Kubernetes-native scheduling, resource management, or policy enforcement?** - * Yes → [Kubernetes backend](/platform/self-hosting/managed-kubernetes/). - * No → [Docker](/platform/self-hosting/managed-docker/) or [Direct](/platform/self-hosting/managed-direct/) is simpler to set up. --- ## Managed architecture -With the managed architecture, you run the `oz-agent-worker` daemon on your infrastructure. The daemon connects to the {VARS.WARP_AUTOMATION_PLATFORM}'s backend, waits for tasks to be assigned to it, and executes those tasks on its host using one of three backends: +With the managed architecture, you run `oz-agent-worker` on your infrastructure. The worker connects to the {VARS.WARP_AUTOMATION_PLATFORM}'s backend, waits for tasks, and handles them with one of four backends: * **[Docker backend](/platform/self-hosting/managed-docker/)** (default) — Runs each task in an isolated Docker container. * **[Kubernetes backend](/platform/self-hosting/managed-kubernetes/)** — Runs each task as a Kubernetes Job in your cluster. * **[Direct backend](/platform/self-hosting/managed-direct/)** — Runs each task directly on the host without a container runtime. +* **[Command backend](/platform/self-hosting/external-orchestrators/#delegating-runs-with-the-command-backend)** — Dispatches each task to an external runtime through a configured command. The worker does not run the agent on its host. -The managed architecture enables full orchestration by the {VARS.WARP_AUTOMATION_PLATFORM} — it can remotely start agents via Slack, Linear, the {VARS.WEB_APP}, the API/SDK, and the `oz agent run-cloud` command. Agents can access host resources through volume mounts (Docker), Kubernetes-native configuration (Kubernetes), and injected environment variables. +The managed architecture enables full orchestration by the {VARS.WARP_AUTOMATION_PLATFORM} — it can remotely start agents via Slack, Linear, the {VARS.WEB_APP}, the API/SDK, and the `oz agent run-cloud` command. Agents can access resources through volume mounts (Docker), Kubernetes-native configuration (Kubernetes), the worker host (Direct), or the configuration applied by an external runtime (Command). ## Unmanaged architecture @@ -119,7 +114,7 @@ You're responsible for executing `oz agent run` on your infrastructure — simil ## Routing runs to self-hosted workers -This section applies to **all managed backends** (Docker, Kubernetes, and Direct). Once a worker is connected, route cloud agent runs to it by specifying the `--host` flag (or equivalent) with your worker ID. The `--host` value must match the `--worker-id` of a connected worker exactly. +This section applies to **all managed backends**. Once a worker is connected, route cloud agent runs to it by specifying the `--host` flag (or equivalent) with your worker ID. The `--host` value must match the `--worker-id` of a connected worker exactly. Docker, Kubernetes, and Direct workers execute the assigned task on worker infrastructure; Command workers dispatch it to the configured external runtime. :::note Unmanaged runs don't need routing — you invoke `oz agent run` directly on the host where you want the agent to execute. Routing is only relevant for managed workers. @@ -214,6 +209,7 @@ For infrastructure-level observability, the `oz-agent-worker` daemon can export * [Managed: Docker](/platform/self-hosting/managed-docker/) — Default managed setup with the Docker backend. * [Managed: Kubernetes](/platform/self-hosting/managed-kubernetes/) — Managed setup with the Kubernetes backend and Helm chart. * [Managed: Direct](/platform/self-hosting/managed-direct/) — Managed setup with no container runtime. +* [External orchestrators](/platform/self-hosting/external-orchestrators/) — Run a Direct worker in one-shot mode or dispatch tasks with the Command backend. * [Self-hosted worker reference](/platform/self-hosting/reference/) — CLI flags and config file schema. * [Monitoring](/platform/self-hosting/monitoring/) — OpenTelemetry metrics for worker health, task throughput, and capacity. * [Security and networking](/platform/self-hosting/security-and-networking/) — Data boundaries, network egress, and security considerations.