> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/ComposioHQ/agent-orchestrator/llms.txt
> Use this file to discover all available pages before exploring further.

# Runtime

> Plugin interface for runtime execution environments where agent sessions execute (tmux, docker, kubernetes, processes)

## Overview

The `Runtime` interface defines how and where agent sessions execute. Runtimes provide isolated execution environments and handle process lifecycle, I/O, and resource management.

**Plugin Slot:** `runtime`\
**Default Plugin:** `tmux`

## Interface Definition

```typescript theme={null}
export interface Runtime {
  readonly name: string;
  
  create(config: RuntimeCreateConfig): Promise<RuntimeHandle>;
  destroy(handle: RuntimeHandle): Promise<void>;
  sendMessage(handle: RuntimeHandle, message: string): Promise<void>;
  getOutput(handle: RuntimeHandle, lines?: number): Promise<string>;
  isAlive(handle: RuntimeHandle): Promise<boolean>;
  getMetrics?(handle: RuntimeHandle): Promise<RuntimeMetrics>;
  getAttachInfo?(handle: RuntimeHandle): Promise<AttachInfo>;
}
```

## Methods

<ResponseField name="name" type="string" required>
  Plugin name identifier (e.g. `"tmux"`, `"docker"`, `"kubernetes"`).
</ResponseField>

<ResponseField name="create" type="(config: RuntimeCreateConfig) => Promise<RuntimeHandle>" required>
  Create a new session environment and return a handle for communication.

  **Parameters:**

  * `config.sessionId` - Unique session identifier
  * `config.workspacePath` - Path to workspace directory
  * `config.launchCommand` - Shell command to launch the agent
  * `config.environment` - Environment variables for the agent process

  **Returns:** RuntimeHandle for the created environment
</ResponseField>

<ResponseField name="destroy" type="(handle: RuntimeHandle) => Promise<void>" required>
  Destroy a session environment and clean up resources.

  **Parameters:**

  * `handle` - Runtime handle from create()
</ResponseField>

<ResponseField name="sendMessage" type="(handle: RuntimeHandle, message: string) => Promise<void>" required>
  Send a text message/prompt to the running agent.

  **Parameters:**

  * `handle` - Runtime handle
  * `message` - Text to send to the agent
</ResponseField>

<ResponseField name="getOutput" type="(handle: RuntimeHandle, lines?: number) => Promise<string>" required>
  Capture recent output from the session.

  **Parameters:**

  * `handle` - Runtime handle
  * `lines` - Optional: number of recent lines to return

  **Returns:** String containing session output
</ResponseField>

<ResponseField name="isAlive" type="(handle: RuntimeHandle) => Promise<boolean>" required>
  Check if the session environment is still alive.

  **Parameters:**

  * `handle` - Runtime handle

  **Returns:** true if environment is running, false otherwise
</ResponseField>

<ResponseField name="getMetrics" type="(handle: RuntimeHandle) => Promise<RuntimeMetrics>">
  Optional: Get resource metrics (uptime, memory, CPU usage).

  **Parameters:**

  * `handle` - Runtime handle

  **Returns:** RuntimeMetrics with resource usage data
</ResponseField>

<ResponseField name="getAttachInfo" type="(handle: RuntimeHandle) => Promise<AttachInfo>">
  Optional: Get info needed to attach a human to this session (for Terminal plugin).

  **Parameters:**

  * `handle` - Runtime handle

  **Returns:** AttachInfo with connection details
</ResponseField>

## Related Types

### RuntimeCreateConfig

```typescript theme={null}
export interface RuntimeCreateConfig {
  sessionId: SessionId;
  workspacePath: string;
  launchCommand: string;
  environment: Record<string, string>;
}
```

Configuration passed to `create()` when spawning a new runtime environment.

<ParamField path="sessionId" type="SessionId" required>
  Unique session identifier
</ParamField>

<ParamField path="workspacePath" type="string" required>
  Absolute path to workspace directory where agent will execute
</ParamField>

<ParamField path="launchCommand" type="string" required>
  Shell command to launch the agent (from Agent.getLaunchCommand())
</ParamField>

<ParamField path="environment" type="Record<string, string>" required>
  Environment variables for the agent process (from Agent.getEnvironment())
</ParamField>

### RuntimeHandle

```typescript theme={null}
export interface RuntimeHandle {
  id: string;
  runtimeName: string;
  data: Record<string, unknown>;
}
```

Opaque handle returned by `create()`, used for all subsequent operations.

<ParamField path="id" type="string" required>
  Runtime-specific identifier (tmux session name, container ID, pod name, etc.)
</ParamField>

<ParamField path="runtimeName" type="string" required>
  Which runtime created this handle (matches Runtime.name)
</ParamField>

<ParamField path="data" type="Record<string, unknown>" required>
  Runtime-specific data (ports, connection strings, etc.)
</ParamField>

### RuntimeMetrics

```typescript theme={null}
export interface RuntimeMetrics {
  uptimeMs: number;
  memoryMb?: number;
  cpuPercent?: number;
}
```

<ParamField path="uptimeMs" type="number" required>
  How long the environment has been running (milliseconds)
</ParamField>

<ParamField path="memoryMb" type="number">
  Memory usage in megabytes
</ParamField>

<ParamField path="cpuPercent" type="number">
  CPU usage percentage (0-100)
</ParamField>

### AttachInfo

```typescript theme={null}
export interface AttachInfo {
  type: "tmux" | "docker" | "ssh" | "web" | "process";
  target: string;
  command?: string;
}
```

<ParamField path="type" type="string" required>
  How to connect: `"tmux"`, `"docker"`, `"ssh"`, `"web"`, or `"process"`
</ParamField>

<ParamField path="target" type="string" required>
  Connection target:

  * For tmux: session name
  * For docker: container ID
  * For web: URL
  * For SSH: host string
</ParamField>

<ParamField path="command" type="string">
  Optional command to run to attach (e.g. `tmux attach -t session-name`)
</ParamField>

## Usage Examples

### Implementing a Runtime Plugin

```typescript theme={null}
import type { Runtime, RuntimeHandle, RuntimeCreateConfig } from "@composio/ao-core";
import { execFile } from "node:child_process";
import { promisify } from "node:util";

const execFileAsync = promisify(execFile);

export function create(): Runtime {
  return {
    name: "tmux",
    
    async create(config: RuntimeCreateConfig): Promise<RuntimeHandle> {
      const { sessionId, workspacePath, launchCommand, environment } = config;
      
      // Create tmux session
      await execFileAsync("tmux", [
        "new-session",
        "-d",
        "-s", sessionId,
        "-c", workspacePath
      ], { timeout: 30_000 });
      
      // Set environment variables
      for (const [key, value] of Object.entries(environment)) {
        await execFileAsync("tmux", [
          "set-environment",
          "-t", sessionId,
          key, value
        ], { timeout: 5_000 });
      }
      
      // Launch agent
      await execFileAsync("tmux", [
        "send-keys",
        "-t", sessionId,
        launchCommand,
        "Enter"
      ], { timeout: 5_000 });
      
      return {
        id: sessionId,
        runtimeName: "tmux",
        data: {}
      };
    },
    
    async destroy(handle: RuntimeHandle): Promise<void> {
      await execFileAsync("tmux", ["kill-session", "-t", handle.id], {
        timeout: 5_000
      });
    },
    
    async sendMessage(handle: RuntimeHandle, message: string): Promise<void> {
      await execFileAsync("tmux", [
        "send-keys",
        "-t", handle.id,
        message,
        "Enter"
      ], { timeout: 5_000 });
    },
    
    async getOutput(handle: RuntimeHandle, lines = 100): Promise<string> {
      const { stdout } = await execFileAsync("tmux", [
        "capture-pane",
        "-t", handle.id,
        "-p",
        "-S", `-${lines}`
      ], { timeout: 5_000 });
      return stdout;
    },
    
    async isAlive(handle: RuntimeHandle): Promise<boolean> {
      try {
        await execFileAsync("tmux", ["has-session", "-t", handle.id], {
          timeout: 5_000
        });
        return true;
      } catch {
        return false;
      }
    }
  };
}
```

### Using Runtime in Session Manager

```typescript theme={null}
import type { Runtime, RuntimeCreateConfig } from "@composio/ao-core";

const runtime: Runtime = registry.get("runtime", "tmux");

const createConfig: RuntimeCreateConfig = {
  sessionId: "my-app-1",
  workspacePath: "/workspace/my-app-1",
  launchCommand: "claude --project . --model claude-sonnet-4-20250514",
  environment: {
    ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,
    SESSION_ID: "my-app-1"
  }
};

const handle = await runtime.create(createConfig);

// Later: send a message
await runtime.sendMessage(handle, "Fix the authentication bug");

// Check if still alive
if (await runtime.isAlive(handle)) {
  console.log("Session is running");
}

// Clean up
await runtime.destroy(handle);
```

## Implementation Notes

### Security Considerations

* **Always use `execFile` instead of `exec`** to prevent shell injection
* **Validate all handle IDs** before using in shell commands
* **Set timeouts** on all external command executions
* **Sanitize environment variables** to prevent code injection

### Error Handling

* Throw errors if runtime operations fail (creation, destruction, messaging)
* Return `false` from `isAlive()` for dead environments (don't throw)
* Handle network errors gracefully for remote runtimes (docker, k8s, SSH)

### Built-in Plugins

* **tmux** - Local tmux sessions (default)
* **process** - Direct Node.js child processes

Future plugins could support Docker, Kubernetes, AWS ECS, SSH remote hosts, cloud sandboxes, etc.

## See Also

* [Agent](/api/agent) - Agent plugin interface
* [Session](/api/session) - Session interface
* [Terminal](/api/terminal) - Terminal UI plugin interface


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.