Skip to content

Extension Development

NJX-njx edited this page Mar 2, 2026 · 1 revision

Extension Development

OpenSoul is built on a plugin-centric architecture. Extensions can add new channels, tools, hooks, and providers.

Overview

Extensions live under extensions/<name>/ and are self-contained packages. They use the public Plugin SDK (opensoul/plugin-sdk) and should never import internal src/* modules directly.

Extension Structure

A typical extension contains:

extensions/my-channel/
├── package.json
├── opensoul.plugin.json    # Plugin manifest
├── index.ts                # Entry point
├── src/                    # Implementation
└── test/                   # Tests

Plugin Manifest (opensoul.plugin.json)

{
  "name": "my-channel",
  "version": "1.0.0",
  "type": "channel",
  "description": "My custom channel adapter",
  "entry": "index.ts"
}

Plugin Types

Channel Plugins

Implement the ChannelPlugin contract to add new messaging platforms:

import type { ChannelPlugin } from "opensoul/plugin-sdk";

export const plugin: ChannelPlugin = {
  name: "my-channel",
  async onMessage(ctx) {
    // Handle incoming messages
  },
  async send(ctx, message) {
    // Send outgoing messages
  },
};

Tool Plugins

Add custom tools that agents can invoke:

import type { ToolPlugin } from "opensoul/plugin-sdk";

export const plugin: ToolPlugin = {
  name: "my-tool",
  description: "A custom tool",
  async execute(ctx, params) {
    // Tool implementation
    return { result: "..." };
  },
};

Hook Plugins

Intercept and modify behavior at various lifecycle points:

import type { HookPlugin } from "opensoul/plugin-sdk";

export const plugin: HookPlugin = {
  name: "my-hook",
  async beforeAgentRun(ctx) {
    // Modify context before agent execution
  },
  async afterAgentRun(ctx, result) {
    // Process results after agent execution
  },
};

Provider Plugins

Add custom model providers or auth mechanisms.

Plugin SDK

The public API surface is available at opensoul/plugin-sdk (src/plugin-sdk/index.ts).

Important: External extensions must use this SDK — do not import from internal src/* paths.

Plugin Lifecycle

  1. Discovery — Gateway scans extensions/ for plugin manifests
  2. Loading — Plugins are loaded and validated
  3. Registration — Plugins register with the plugin registry
  4. Runtime — Plugins receive events and API calls through the runtime API

Key source modules:

  • src/plugins/loader.ts — Plugin loading and discovery
  • src/plugins/registry.ts — Plugin registration
  • src/plugins/runtime/ — Plugin runtime API

Existing Extensions

Extension Type Description
discord Channel Discord bot integration
telegram Channel Telegram bot (grammY)
slack Channel Slack workspace integration
whatsapp Channel WhatsApp via Baileys
signal Channel Signal messenger
matrix Channel Matrix protocol
feishu Channel Feishu/Lark
line Channel LINE messaging
msteams Channel Microsoft Teams
voice-call Feature Voice call support
memory-core Feature Memory system core
memory-lancedb Feature LanceDB vector memory
llm-task Feature LLM task execution
diagnostics-otel Feature OpenTelemetry diagnostics
copilot-proxy Feature Copilot proxy

Config Schema Integration

Channel plugins can register config schemas and UI hints:

export const configSchema = {
  type: "object",
  properties: {
    apiToken: {
      type: "string",
      description: "API token for the channel",
      sensitive: true,
    },
  },
};

The Control UI automatically renders forms for plugin config schemas.

Testing Extensions

Tests are colocated with extensions:

# Run extension tests
pnpm test --config vitest.extensions.config.ts

Related Pages

Clone this wiki locally