# How to Extend and Customize LoopX: A Complete Guide to Extensions and Custom Runtimes

> Discover how to extend and customize LoopX with its scaffold-based system, provider implementations, and sandboxed runtimes. Add new capabilities easily without core code modification.

- Repository: [huangruiteng/loopx](https://github.com/huangruiteng/loopx)
- Tags: how-to-guide
- Published: 2026-08-13

---

**Yes, LoopX is built for extensibility, offering a scaffold-based extension system, provider implementations, and sandboxed runtime environments that let you add capabilities without modifying core code.**

LoopX is an open-source control-plane framework designed with **extension points** as first-class citizens. Whether you need to integrate external APIs like Lark Kanban or embed LoopX into existing agent infrastructure, its architecture separates core logic from pluggable components. Understanding how to extend and customize LoopX allows you to introduce domain-specific capabilities while maintaining the platform's robust quota, evidence, and scheduler contracts.

## Core Extension Architecture

LoopX organizes extensibility into four distinct layers. Each layer has a specific purpose and well-defined source files that handle different aspects of the extension lifecycle.

### Extension Scaffold

The **scaffold layer** provides a thin helper for creating new extension packages. Located in [[`loopx/extensions/scaffold.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/scaffold.py)](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/scaffold.py), the `create_extension()` function generates the required file layout and [`extension.toml`](https://github.com/huangruiteng/loopx/blob/main/extension.toml) manifest automatically. This utility ensures that new providers, capabilities, or integrations follow the correct directory structure from the start.

### Runtime Engine

The **runtime engine** handles discovery, activation, and lifecycle management of extensions. The core loader in [[`loopx/extensions/runtime.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/runtime.py)](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/runtime.py) activates extensions at startup, validates their manifests, and enforces the public-private boundary. This layer supports custom runtime adapters, periodic reporters, and data sinks while keeping extensions sandboxed.

### Provider Implementations

**Providers** contain the concrete business logic that implements a capability's behavior. For example, [[`loopx/extensions/lark/provider.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/lark/provider.py)](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/lark/provider.py) demonstrates a real-world implementation integrating Lark Kanban. Providers are Python classes that receive input payloads through the `ExecutionEnvelope` and return structured responses.

### Manifest System

Every extension requires an **[`extension.toml`](https://github.com/huangruiteng/loopx/blob/main/extension.toml)** manifest that declares capability IDs, dependencies, and activation rules. The manifest parser in [[`loopx/extensions/manifest.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/manifest.py)](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/manifest.py) reads these files to register capabilities with the CLI. This allows LoopX to discover extensions automatically and enforce contracts at runtime.

## Creating a Custom LoopX Extension

Building a new extension involves four concrete steps: scaffolding the structure, implementing the provider logic, declaring capabilities in the manifest, and registering the extension with the runtime.

### Step 1: Scaffold the Extension

Use the scaffold utility to generate the boilerplate directory structure:

```python
from loopx.extensions.scaffold import create_extension

create_extension(
    name="my_custom_extension",
    capability_id="my_capability",
    description="Demo provider that echoes a message",
)

```

This creates the following layout under `loopx/extensions/my_custom_extension/`:

```text
loopx/extensions/my_custom_extension/
│─ __init__.py
│─ provider.py          # Implementation logic

│─ extension.toml       # Capability declaration

```

### Step 2: Implement the Provider

Create a provider class that implements the business logic. The class must expose a `run` method that accepts a dictionary payload:

```python

# loopx/extensions/my_custom_extension/provider.py

from loopx.extensions.execution_envelope import ExecutionEnvelope

class MyProvider:
    def run(self, input_payload: dict) -> dict:
        msg = input_payload.get("message", "hello")
        return {"echo": f"[my_provider] {msg}"}

```

### Step 3: Declare Capabilities

Define the extension metadata and activation conditions in [`extension.toml`](https://github.com/huangruiteng/loopx/blob/main/extension.toml):

```toml

# loopx/extensions/my_custom_extension/extension.toml

[extension]
id = "my_custom_extension"
capability = "my_capability"
description = "Simple echo provider"

[activation]
required_capabilities = ["shell"]

```

The `required_capabilities` field specifies which host capabilities must be present for the extension to activate.

### Step 4: Register and Use

Register the extension by placing the folder under `loopx/extensions/` or publishing it as a separate package loadable by the manifest loader. Once installed, the LoopX CLI exposes the new capability:

```bash
loopx quota should-run \
  --goal-id <goal-id> \
  --agent-id <agent-id> \
  --available-capability my_capability

```

The CLI packet now contains a `my_capability` field, and LoopX automatically enforces quota, writes back state, and records evidence.

## Custom Runtime Integration

LoopX supports embedding into existing agent runners without replacing your orchestration layer. The approach documented in [[`docs/guides/custom-agent-runner-integration.md`](https://github.com/huangruiteng/loopx/blob/main/docs/guides/custom-agent-runner-integration.md)](https://github.com/huangruiteng/loopx/blob/main/docs/guides/custom-agent-runner-integration.md) uses a three-piece separation model.

### The Three-Piece Model

| Component | Owns | Does Not Own |
|-----------|------|--------------|
| **LoopX CLI** | Durable goals, todos, quotas, evidence, scheduler hints | Agent reasoning, tool execution |
| **Lightweight skill** | How the Agent reads a LoopX packet and writes back | Task state or external scheduling |
| **Your runner** | Wake-ups, workspace setup, invoking the Agent | LoopX policy or domain truth |

### Integration Steps

1. **Bootstrap** the LoopX CLI on the host machine using the install script from the integration guide
2. **Request a packet** using `loopx agent-onboard …` to receive quota guards, bootstrap commands, and declared capabilities
3. **Execute a bounded turn** using the packet's `should-run` gate, perform work, then write back with `loopx refresh-state`
4. **Acknowledge scheduler hints** apply the hint returned by LoopX and ACK it to prevent double spending

A runnable minimal example in [[`examples/custom-runtime-minimal-cli-turn-smoke.py`](https://github.com/huangruiteng/loopx/blob/main/examples/custom-runtime-minimal-cli-turn-smoke.py)](https://github.com/huangruiteng/loopx/blob/main/examples/custom-runtime-minimal-cli-turn-smoke.py) demonstrates a full turn:

```bash
python3 examples/custom-runtime-minimal-cli-turn-smoke.py

```

This script pulls a packet, evaluates `quota should-run`, executes a dummy task, validates results, writes back state, and acknowledges scheduler hints—all without requiring a permanent LoopX leader process.

## Summary

- **LoopX is architected for extensibility** through four layers: scaffold utilities, runtime engines, provider implementations, and manifest declarations.
- **Extensions require four components**: a scaffolded directory, a provider class with a `run` method, an [`extension.toml`](https://github.com/huangruiteng/loopx/blob/main/extension.toml) manifest, and registration with the runtime.
- **Providers run sandboxed** with automatic quota enforcement, evidence recording, and state management handled by the core runtime.
- **Custom integration is supported** via a three-piece model that lets you embed LoopX capabilities into existing agent runners without giving up control over orchestration.
- **Source files to examine**: [[`loopx/extensions/scaffold.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/scaffold.py)](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/scaffold.py), [[`loopx/extensions/runtime.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/runtime.py)](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/runtime.py), and [[`loopx/extensions/manifest.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/manifest.py)](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/manifest.py).

## Frequently Asked Questions

### How do I create a new extension in LoopX?

Use the `create_extension()` function from [[`loopx/extensions/scaffold.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/scaffold.py)](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/scaffold.py) to generate the directory structure, then implement your provider logic in the generated [`provider.py`](https://github.com/huangruiteng/loopx/blob/main/provider.py) file and declare capabilities in [`extension.toml`](https://github.com/huangruiteng/loopx/blob/main/extension.toml). The test suite in [[`tests/extensions/test_extension_scaffold.py`](https://github.com/huangruiteng/loopx/blob/main/tests/extensions/test_extension_scaffold.py)](https://github.com/huangruiteng/loopx/blob/main/tests/extensions/test_extension_scaffold.py) validates this workflow.

### Can I use LoopX with my existing agent runner without replacing it?

Yes. LoopX supports custom runtime integration through a lightweight skill pattern documented in [[`docs/guides/custom-agent-runner-integration.md`](https://github.com/huangruiteng/loopx/blob/main/docs/guides/custom-agent-runner-integration.md)](https://github.com/huangruiteng/loopx/blob/main/docs/guides/custom-agent-runner-integration.md). Your runner owns wake-ups and workspace setup while LoopX handles quotas and evidence, communicating via CLI commands like `loopx agent-onboard` and `loopx refresh-state`.

### What is the purpose of the extension.toml manifest file?

The [`extension.toml`](https://github.com/huangruiteng/loopx/blob/main/extension.toml) file declares an extension's **capability IDs**, **dependencies**, and **activation rules**. Parsed by [[`loopx/extensions/manifest.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/manifest.py)](https://github.com/huangruiteng/loopx/blob/main/loopx/extensions/manifest.py), it enables automatic discovery and enforces the public-private boundary by specifying which host capabilities must be present for activation.

### How does LoopX ensure extensions run safely?

All extensions execute in a **sandboxed environment** that respects LoopX's public-private boundary. The runtime validates inputs, enforces quota limits, and records evidence before any external side-effects occur. This architecture prevents extensions from bypassing core policy controls while still allowing flexible customization.