Chatelope
Plugins

Creating Plugins

Developer guide for building Chatelope plugins

Creating Plugins

This guide covers how to create custom plugins for Chatelope using the Plugin SDK.

Getting Started

Prerequisites

  • Node.js 18+
  • npm or pnpm
  • TypeScript knowledge
  • Familiarity with Chatelope

Create a Plugin Project

npx create-chatelope-plugin my-plugin
cd my-plugin
npm install

This creates a project structure:

my-plugin/
├── src/
│   └── index.ts       # Main plugin entry
├── package.json
├── tsconfig.json
└── chatelope.config.ts # Plugin manifest

Plugin Manifest

Configure your plugin in chatelope.config.ts:

import { definePlugin } from '@chatelope/plugin-sdk';

export default definePlugin({
  id: 'my-plugin',
  name: 'My Plugin',
  version: '1.0.0',
  description: 'Description of what the plugin does',
  author: 'Your Name',

  // Permissions required
  permissions: [
    'conversations:read',
    'network',
  ],

  // Plugin type
  type: 'parser', // or 'provider', 'integration'
});

Plugin Types

Parser Plugin

Import conversations from new sources:

// src/index.ts
import { defineParser, ParsedConversation } from '@chatelope/plugin-sdk';

export default defineParser({
  id: 'my-parser',
  name: 'My Platform',
  version: '1.0.0',

  detect: async (file) => {
    // Return true if this parser can handle the file
    const content = await file.text();
    return content.includes('"myPlatform"');
  },

  parse: async (file): Promise<ParsedConversation[]> => {
    const data = JSON.parse(await file.text());
    return transformData(data);
  },
});

Provider Plugin

Add AI chat providers:

// src/index.ts
import { defineProvider, Message } from '@chatelope/plugin-sdk';

export default defineProvider({
  id: 'my-provider',
  name: 'My AI Service',
  version: '1.0.0',

  config: {
    apiKey: { type: 'string', secret: true, required: true },
  },

  getModels: async (config) => {
    return [
      { id: 'model-1', name: 'Model One' },
      { id: 'model-2', name: 'Model Two' },
    ];
  },

  chat: async function* (messages, config, options) {
    // Implement chat logic
    yield { content: 'Response text' };
  },
});

Integration Plugin

Connect to external services:

// src/index.ts
import { defineIntegration } from '@chatelope/plugin-sdk';

export default defineIntegration({
  id: 'my-integration',
  name: 'My Service',
  version: '1.0.0',

  config: {
    apiKey: { type: 'string', secret: true },
  },

  // Hook into Chatelope events
  hooks: {
    onConversationCreated: async (conversation, config) => {
      // Do something when a conversation is created
    },

    onMessageSent: async (message, config) => {
      // Do something when a message is sent
    },
  },
});

Configuration Schema

Define user-configurable options:

config: {
  // Text input
  apiKey: {
    type: 'string',
    label: 'API Key',
    description: 'Your API key from the provider',
    secret: true,     // Masked input
    required: true,
  },

  // Number input
  timeout: {
    type: 'number',
    label: 'Timeout',
    default: 30,
    min: 1,
    max: 120,
  },

  // Boolean toggle
  enableDebug: {
    type: 'boolean',
    label: 'Debug Mode',
    default: false,
  },

  // Select dropdown
  model: {
    type: 'select',
    label: 'Model',
    options: [
      { value: 'fast', label: 'Fast' },
      { value: 'quality', label: 'Quality' },
    ],
  },
}

Development

Running Locally

npm run dev

This starts a development server with hot reload.

Testing

Write tests for your plugin:

// src/index.test.ts
import { test, expect } from 'vitest';
import plugin from './index';

test('detects valid files', async () => {
  const file = new File(['{"myPlatform": true}'], 'export.json');
  expect(await plugin.detect(file)).toBe(true);
});

Run tests:

npm test

Building

npm run build

Creates a distributable package in dist/.

Publishing

To npm

npm publish

To Plugin Directory

  1. Fork the plugin-directory repository
  2. Add your plugin manifest
  3. Submit a pull request

Verification

For official verification:

  1. Submit for review
  2. Pass security audit
  3. Meet quality standards
  4. Receive verified badge

Best Practices

Error Handling

try {
  const result = await apiCall();
} catch (error) {
  if (error.code === 'NETWORK_ERROR') {
    throw new PluginError('Network unavailable', 'network');
  }
  throw new PluginError('Unknown error', 'unknown', error);
}

Logging

import { logger } from '@chatelope/plugin-sdk';

logger.info('Processing file');
logger.debug('Parsed data:', data);
logger.error('Failed to parse', error);

Progress Reporting

parse: async (file, { onProgress }) => {
  const lines = content.split('\n');
  const results = [];

  for (let i = 0; i < lines.length; i++) {
    results.push(parseLine(lines[i]));
    onProgress((i / lines.length) * 100);
  }

  return results;
}

API Reference

Full SDK documentation:

Examples

Browse example plugins:

On this page