Skip to content

Latest commit

 

History

History
202 lines (140 loc) · 15.7 KB

self-hosted.md

File metadata and controls

202 lines (140 loc) · 15.7 KB
title Self-hosted executors

A self_hosted Session runs on a machine your application owns: a workstation, a VM or a sandbox you manage. The application creates the Session through /v1 and receives a command that installs oac-daemon, starts it and connects it to Core. Web shows the same command on the Session's page; it is optional. Core never creates, stops or reclaims the machine.

The daemon is not a sandbox. Tools run with the permissions of the account that starts it and can reach whatever that account can. Use a container or VM when you need isolation; see Runtime and outer isolation. The daemon does not restrict network access, so a Template that requires a network policy is rejected for a self-hosted Session.

The Session brings its own model provider; the installation default never applies (why). The machine gets an executor credential that works for this one Environment and nothing else.

Platforms

Platform Codex Claude Code MiniMax Code
Linux amd64 Supported Supported Supported
macOS arm64 Supported Supported Supported
Windows amd64 Supported Supported Not supported

The installer brings its own pinned Node.js and Harness versions (listed in scripts/build-native-installer.mjs) and leaves other installations of those tools untouched. On a platform without a matching installer, the command fails.

The download is about 320 MiB. At its peak the installation needs about 2 GiB free on the disk that holds the Runtime home and the installation directory with one Harness selected (archive 316 MiB, unpacked installer 907 MiB, installed files about 560 MiB), and about 2.2 GiB with all three; the unpacked copy is removed when the command ends and the archive when the installation completes. The finished installation takes about 560 MiB with one Harness and about 940 MiB with all three.

The machine needs:

  • HTTP or HTTPS access to Core, and to the release download host unless Core carries an offline copy of the installers;
  • Bash for environment setup and MiniMax Code tools; on Windows, Git Bash, which Claude Code also requires;
  • Python and pip when the Session's packages need them;
  • any system packages your setup needs. The daemon never runs apt, sudo or another elevation command, so install them through the host's normal administration.

No administrator privileges or Docker are needed. The Unix download command also uses curl, tar, gzip, a SHA-256 tool and the system file-lock command (flock on Linux, lockf on macOS). Windows needs its system tar.exe; the command checks for it before downloading. The Runtime home must allow executable files to run. On a Unix noexec mount, choose another absolute directory with OAC_RUNTIME_HOME before running the command.

Connect a machine

  1. Choose an absolute workspace path on the target machine. Create a Session with that path and the application's Project API key:

    import os
    from openai import OpenAI
    
    client = OpenAI()  # reads OPENAI_BASE_URL and OPENAI_API_KEY
    session = client.beta.agents.sessions.create(
        environment={
            "type": "self_hosted",
            "workspace_directory": os.environ["EXECUTOR_WORKSPACE"],
        },
        extra_body={
            "agent": {"model": os.environ["MODEL_NAME"], "x_agents_core": {"harness": "codex"}},
            "x_agents_core": {"model_provider": {
                "protocol": "responses",
                "base_url": os.environ["MODEL_BASE_URL"],
                "api_key": os.environ["MODEL_API_KEY"],
            }},
        },
    )
    installation = session.model_dump()["x_agents_core"]["installation"]
    print(installation["commands"]["posix"])  # use "powershell" on Windows
  2. Run the command on the target machine with the account that should run the tools. It downloads the installer matched to this Core, verifies its checksum, asks which Harnesses to install and where, installs them, creates the workspace if needed, starts the daemon and checks its connection.

  3. Send a Turn. A connected machine proves only authentication; the first Turn checks the Harness and the model.

In Web, open the Session and copy the command under Connect a host.

Keep the command private: it carries a short-lived installation grant that claims the machine's credential. The command passes the grant in the OAC_INSTALL_GRANT environment variable, never as an argument. On Linux and macOS it starts with a space so shells that skip space-prefixed commands leave it out of history. PowerShell has no such rule: its history file (ConsoleHost_history.txt) keeps the whole command, grant included, until you clear it, although the grant stops working after 30 minutes. When it has expired, read the Session again or copy a fresh command from Web.

The installer reports three results:

Result Meaning
Installation The selected Harnesses passed their readiness checks
Daemon connection Core confirmed the daemon's authenticated connection
Model configuration Not checked; the first Turn uses the Session's model provider

The installer checks the grant before it downloads anything, so an expired command costs no download. The archive download resumes after a reset, fails only when it stalls (no data for 60 seconds) and gives up after five attempts; rerun the command to continue where it stopped. A verified archive is kept in native-download under the Runtime home until the installation completes, so a rerun after a failure needs no new download; it is checked against Core's checksum on every run and discarded if it fails. Disk space is checked before downloading, extracting and copying components. If a download or installation is interrupted, rerun the command: it clears unfinished temporary copies while preserving completed components, credentials and the workspace. The small download.lock file in native-download remains for concurrency control. An active download or installation is never cleared by another run. If the command expires, copy a fresh one from the Session.

If the connection is not confirmed within 45 seconds, the installer prints the path of the daemon's log. The daemon keeps reconnecting. Fix the cause and run the install command again with the same installation directory, copying a fresh one from Web if it has expired: completed components and the credential are kept and a running daemon is reused. Do not remove the workspace or the Session to retry.

Options for automation

Append these to the command:

Option Effect
--non-interactive Never prompt; missing input fails
--harness codex,claude,minimax Harnesses to install, comma-separated. Must include the Session's Harness
--install-dir ABS Installation directory. It must be missing, empty or hold an installation; any other non-empty directory is refused. Default: environments/<environment-id> under ~/.oac, or under OAC_RUNTIME_HOME when set
--capability-directory ABS Where capability snapshots are stored. Default: capabilities in the installation directory
--tool-env-file ABS A JSON file of string variables for tools and MCP servers; see explicit local tool environment

The workspace is fixed when the Session is created. For a different workspace, create another Session.

Local capability directories

A self-hosted Session may supply capability_directories alongside its workspace:

environment = {
    "type": "self_hosted",
    "workspace_directory": os.environ["EXECUTOR_WORKSPACE"],
    "capability_directories": [os.environ["EXECUTOR_CAPABILITIES"]],
}

Paths are absolute in the machine's own syntax (Unix, Windows drive or UNC); the daemon checks them, not Core. Fill these directories before the daemon connects. They are ordinary paths visible to the daemon; naming one does not mount it or create a sandbox.

Use x_agents_core.environment for the same Project-owned Skills, Plugin archives, files, packages, setup commands or Template used by a managed Session:

session = client.beta.agents.sessions.create(
    agent_id=agent_id,
    environment=environment,
    extra_body={"x_agents_core": {
        "model_provider": model_provider,
        "environment": {"environment_template_id": template_id},
    }},
)

The same extension works with environment={"type": "openai_hosted"}. Do not repeat a field in both environment and the extension. Setup runs with the daemon's account permissions. Deployment model keys are never sent to your machine.

Before the first Turn the daemon copies these sources into a snapshot. Reconnecting reuses the snapshot even after you edit the sources; a new Session takes a new snapshot. The preparation contract lists fields, merge rules, snapshot behavior and failures.

Operate the installation

The installation's bin/oac-daemon finds its own installation. Use it for:

Command Effect
oac-daemon start Validate the installed Harnesses and start the daemon in the background
oac-daemon status Show the local profile and process; not the connection
oac-daemon logs -n 100, oac-daemon logs -f Print or follow the daemon log
oac-daemon stop Stop the daemon
oac-daemon uninstall Remove the machine

The installed bin/oac-daemon ignores OAC_RUNTIME_HOME and always acts on its own installation. Nothing restarts the daemon after a reboot: run bin/oac-daemon start again, which keeps the installation, credential and history. Check the connection under Host connection on the Session's page in Web, or with the connection status.

To add a Harness, run the install command again (a fresh copy from Web if it has expired) with the same installation directory and the Harness to add. The installer checks the existing contents, adds only missing components and keeps the Harnesses already installed. Restart a running daemon afterwards so it discovers the new Harness.

Stopping the daemon, cancelling a Turn or deleting the Session never removes the machine's workspace, native history or capability snapshot. An installation from another daemon version, or one whose files were changed, is refused. The installer never upgrades, repairs or migrates it. To use the Session on a new directory, reconnect it.

Remove a machine {#remove-a-machine}

Run the installation's own command:

"$HOME/.oac/environments/<environment-id>/bin/oac-daemon" uninstall

On Windows PowerShell:

& "$HOME\.oac\environments\<environment-id>\bin\oac-daemon.exe" uninstall

It stops the daemon, lists what it deletes and asks for confirmation. It deletes only what an installation owns inside its directory (bin, daemon, components, capabilities, runtime, initialization and packages, with their credential file, native history and Harnesses) and then the directory itself if nothing else is left in it. Anything else in the directory stays, and so do the workspace and any credential file or capability directory outside the installation; the command names each one it keeps. The native-download directory and its download.lock are never touched. Where nothing is installed it says so and exits 0. If a file cannot be deleted, the command names it and can be run again once it is released. On Windows, the final deletion finishes a few seconds after the command exits.

Then, in Web, open the Session and choose Revoke in Executor credentials, or Delete the Session; Core keeps accepting the machine's credential until you do.

The Session's install command cannot connect the machine again: its credential stays claimed in Core. To reconnect the Session, choose Rotate and install from an extracted distribution, or create a new Session.

After a Session is deleted or its credential is revoked or rotated, the daemon started with start prints why in connect.log (see oac-daemon logs) and exits. Starting it again prints the same reason. To reconnect it, follow Rotate or revoke or Reconnect an existing Session; to remove it, run uninstall.

Rotate or revoke

In Web, the Session's Executor credentials list the machine's credential:

Action Effect
Rotate The credential gets a new secret; the old secret stops working at once. On a revoked credential the action is Restore
Revoke The credential stops working at once

To reconnect after a rotation, stop the daemon with oac-daemon stop, replace the JSON at its configured credential-file path with the new credential, and run oac-daemon start. Do not run install again over the existing installation, and rotate the existing credential rather than issuing a second one, which cannot connect.

In an archived Project, credentials cannot be issued or rotated; revocation remains available. Operators can manage credentials with the Core key; see the credential contract.

Reconnect an existing Session {#reconnect-an-existing-session}

The install command claims the Session's machine credential once, and a second claim ends in This Session's machine credential is already claimed by another installation. That happens when you run the command in a different directory, on another machine, after the installation directory was lost, or when the directory holds an installation of another Core build or Session, which the installer refuses to change. Rerunning the command in the original directory always works.

To reconnect the Session without the original directory, rotate its credential and install from an extracted distribution into a new directory:

  1. In Web, open the Session and choose Rotate in Executor credentials. Save the credential JSON it returns.
  2. Download <base>/<platform>.tar.gz and extract it, where <base> is the first URL of the install command (it ends with the Core version) and <platform> is linux-amd64, linux-arm64, darwin-arm64 or windows-amd64.
  3. Run the installer as in Install from an extracted distribution with the Session's remote_url, Environment ID, workspace and the saved credential file.

Or create a new Session and run its command.

Install from an extracted distribution

The same installer accepts an already extracted distribution and a credential file issued by an operator, without the install command:

./oac-daemon install --non-interactive --harness codex \
  --install-dir "$HOME/.oac/my-runtime" \
  --remote 'wss://core.example/api/v1/agent-daemon/ws' \
  --environment-id '11111111-2222-4333-8444-555555555555' \
  --workspace "$HOME/workspace" \
  --credential-file "$HOME/executor-credential.json"
"$HOME/.oac/my-runtime/bin/oac-daemon" start

Use the Session's remote_url and Environment ID. The distribution is the archive named in Reconnect an existing Session. In PowerShell, run .\oac-daemon.exe with native absolute paths. The installation directory must be missing, empty or hold an installation. This mode needs an existing workspace and does not start the daemon until you run start.