How to Extend and Customize LoopX: A Complete Guide to Extensions and Custom Runtimes
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), the create_extension() function generates the required file layout and 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) 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) 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 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) 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:
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/:
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:
# 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:
# 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:
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) 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
- Bootstrap the LoopX CLI on the host machine using the install script from the integration guide
- Request a packet using
loopx agent-onboard …to receive quota guards, bootstrap commands, and declared capabilities - Execute a bounded turn using the packet's
should-rungate, perform work, then write back withloopx refresh-state - 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) demonstrates a full turn:
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
runmethod, anextension.tomlmanifest, 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), [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).
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) to generate the directory structure, then implement your provider logic in the generated provider.py file and declare capabilities in 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) 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). 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 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), 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →