Skip to content

Runtimes

A LanguageAgentRuntime is a cluster-scoped preset that packages the defaults for a specific agent type: container image, ports, resource limits, probes, and init containers. It is analogous to a Kubernetes StorageClass — admins install runtimes once, users reference them by name.

spec:
  runtime: openclaw

How It Works

At reconcile time, the operator merges the runtime's defaults into the agent's effective spec before creating any Kubernetes resources. The agent's own fields always take precedence for scalar values; lists are runtime-first, then agent-appended.

This means a minimal agent spec like:

apiVersion: langop.io/v1alpha1
kind: LanguageAgent
metadata:
  name: my-agent
spec:
  runtime: openclaw
  models:
    - name: claude-sonnet

produces the same pod spec as if the agent had explicitly specified the OpenClaw image, port, init containers, and probes — because the runtime supplies those defaults. Workspace storage is provisioned per-agent (always defaulted to /workspace), not by the runtime.

Bundled Runtimes

Eight runtimes are shipped via the language-operator-runtimes umbrella chart, installed independently after the operator. Each runtime lives in its own repository and is pulled in as a subchart from oci://ghcr.io/language-operator/charts:

Name Image Port Interface Repository
openclaw ghcr.io/openclaw/openclaw:latest 18789 WebSocket gateway openclaw-adapter
opencode ghcr.io/language-operator/opencode-adapter 8080 HTTP / WebSocket terminal opencode-adapter
claude-code ghcr.io/language-operator/claude-code-adapter 8080 HTTP / WebSocket terminal claude-code-adapter
deepagents ghcr.io/language-operator/deepagents-adapter 8080 HTTP / A2A deepagents-adapter
kilo ghcr.io/language-operator/kilo-adapter 8080 HTTP / WebSocket terminal kilo-adapter
qwen-code ghcr.io/language-operator/qwen-code-adapter 8080 HTTP / WebSocket terminal qwen-code-adapter
cursor ghcr.io/language-operator/cursor-adapter 8080 HTTP / WebSocket terminal (vendor key, bypasses the gateway) cursor-adapter
goose ghcr.io/language-operator/goose-adapter 8080 HTTP / WebSocket terminal goose-adapter

The opencode, claude-code, kilo, qwen-code, cursor and goose images share the coding-runtime base image, which translates /etc/agent/config.yaml into the CLI's config and serves the browser terminal. Each runtime chart pins its own image tag.

Install them all with the umbrella chart:

helm install language-operator-runtimes \
  language-operator/language-operator-runtimes \
  --namespace language-operator

Or install a single runtime directly from its OCI chart:

helm install claude-code \
  oci://ghcr.io/language-operator/charts/claude-code \
  --namespace language-operator

Any runtime can be disabled at install time via its top-level values.yaml key (which matches the subchart name):

claude-code:
  enabled: false

See Installation for the full install sequence.

Merge Semantics

Field type Behaviour
Scalars (image, resources, probes, execution.*) Runtime provides the default; agent overrides if set
ports Replace semantics — runtime ports apply only when the agent specifies no ports
Lists (env, envFrom, volumes, volumeMounts, initContainers) Runtime entries prepended; agent entries appended
deployment.replicas, deployment.autoscaling Not merged — agents run as Argo Workflows, which have neither

A runtime can also default the execution model through spec.execution, so an image that only makes sense as a one-shot job can ship with mode: task without every agent restating it. See Execution Modes.

Example: An OpenClaw runtime defines an init container that adapts /etc/agent/config.yaml into OpenClaw's native format. An agent using runtime: openclaw can add its own init containers; they run after the runtime's adapter.

Credentials

Runtimes provision credentials for every agent that uses them through the generic credentials list. Each entry's name is both the environment variable name and the key in the operator-managed Secret. Entries are resolved in priority order:

  • valueFrom set — the referenced Secret's keys are injected via envFrom; the operator creates no Secret of its own.
  • value set — the literal is stored in an operator-managed Secret named {agent-name}-runtime and injected via envFrom.
  • neither set — the operator auto-generates a random value once, persists it in the {agent-name}-runtime Secret, and preserves it across reconciles (it is never rotated).

The bundled runtimes declare the credentials their images need:

  • openclaw declares OPENCLAW_GATEWAY_TOKEN (auto-generated).
  • opencode declares no credentials — access is gated by the cluster OIDC proxy (auth.enabled: true).
  • claude-code declares no credentials — authentication is interactive via /login.
  • deepagents declares no credentials — LLM traffic goes through the injected MODEL_ENDPOINT gateway.
  • kilo declares no credentials — Kilo reaches models through the gateway; access to the terminal is gated by the cluster OIDC proxy (auth.enabled: true).
  • qwen-code declares no credentials — Qwen Code reaches models through the gateway; access to the terminal is gated by the cluster OIDC proxy (auth.enabled: true).
  • cursor declares CURSOR_API_KEY only when the chart value credentials.apiKeySecret names a Secret; otherwise each agent sets it in spec.credentials or signs in interactively. Cursor talks to Cursor directly, not through the gateway.
  • goose declares no credentials — Goose reaches models through the gateway; access to the terminal is gated by the cluster OIDC proxy (auth.enabled: true).

Runtime-declared entries merge first, then any entries the agent adds in its own spec.credentials; entries are deduplicated by name, with the agent's entry winning on a collision.

Authentication

Authentication is a runtime trait, not an agent setting. A runtime's spec.auth.enabled: true gates whether agents using it sit behind the cluster's OIDC proxy. An agent is proxied only when both the cluster has auth.enabled: true and its runtime has auth.enabled: true. The eight bundled runtimes all enable auth since they serve web UIs. See Clusters for the cluster-side configuration.

Custom Runtimes

Any container image can be packaged as a runtime:

apiVersion: langop.io/v1alpha1
kind: LanguageAgentRuntime
metadata:
  name: my-python-agent
spec:
  image: ghcr.io/my-org/python-agent:v1.0.0
  ports:
    - name: http
      port: 8080
  deployment:
    resources:
      requests:
        memory: 512Mi
        cpu: 200m
      limits:
        memory: 2Gi
        cpu: 1000m
    livenessProbe:
      httpGet:
        path: /health
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 30
    initContainers:
      - name: config-adapter
        image: ghcr.io/my-org/config-adapter:v1.0.0

LanguageAgentRuntime is cluster-scoped — one runtime can be referenced by agents in any namespace.