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

# Plugin SDK Overview

> Build plugins for AIRI using the Plugin SDK and protocol

<Warning>
  The `@proj-airi/plugin-sdk` is currently in active development. APIs may change without warning.
</Warning>

## Overview

The Plugin SDK enables developers to create plugins that extend AIRI's capabilities. Plugins can provide AI models, tools, integrations, and custom features through a standardized lifecycle and communication protocol.

## Installation

```bash theme={null}
npm install @proj-airi/plugin-sdk
```

## Architecture

The Plugin SDK follows a host-guest architecture:

* **Plugin Host**: Manages plugin lifecycle, communication channels, and capability orchestration
* **Plugins**: Independent modules that contribute features through a standardized protocol
* **Channels**: Transport-agnostic communication layer (in-memory, WebSocket, Worker)
* **Protocol**: Structured events and lifecycle phases

```mermaid theme={null}
flowchart TB
    Host[Plugin Host]
    P1[Plugin A]
    P2[Plugin B]
    P3[Plugin C]
    
    Host -->|Channel| P1
    Host -->|Channel| P2
    Host -->|Channel| P3
    
    P1 -->|Events| Host
    P2 -->|Events| Host
    P3 -->|Events| Host
    
    Host -->|Registry Sync| P1
    Host -->|Registry Sync| P2
    Host -->|Registry Sync| P3
```

## Key Concepts

### Plugin Lifecycle

Plugins progress through defined phases:

1. **Loading** - Plugin module is imported
2. **Loaded** - Plugin is successfully loaded
3. **Authenticating** - Establishing secure connection
4. **Authenticated** - Authentication successful
5. **Announced** - Plugin registered in module registry
6. **Preparing** - Checking dependencies and prerequisites
7. **Prepared** - Ready for configuration
8. **Configuration Needed** - Waiting for user configuration
9. **Configured** - Configuration applied
10. **Ready** - Plugin is fully active

### Transport Types

The SDK supports multiple transport mechanisms:

* **In-Memory**: Direct function calls within the same process
* **WebSocket**: Remote communication over network (planned)
* **Worker**: Web Workers or Node.js worker threads (planned)
* **Electron IPC**: Electron main/renderer process communication (planned)

### Capabilities

Plugins contribute capabilities that other plugins can depend on:

```typescript theme={null}
// Plugin A announces a capability
await apis.protocol.capabilities.markReady('llm:openai')

// Plugin B waits for the capability
await apis.protocol.capabilities.wait('llm:openai')
```

## Basic Plugin Structure

```typescript theme={null}
import { definePlugin } from '@proj-airi/plugin-sdk'

export default definePlugin('my-plugin', '1.0.0', () => ({
  async init({ channels, apis }) {
    // Initialize plugin
    console.log('Plugin initializing...')
    
    // Register event handlers
    channels.host.on('module:configure', async (event) => {
      const config = event.payload.config
      // Apply configuration
    })
    
    return true // or false to abort
  },
  
  async setupModules({ channels, apis }) {
    // Contribute capabilities
    await apis.protocol.capabilities.markReady('my-feature')
    
    // Setup module functionality
    channels.host.on('custom:event', async (event) => {
      // Handle custom events
    })
  }
}))
```

## Plugin Manifest

Plugins are loaded via a manifest that specifies entrypoints for different runtimes:

```typescript theme={null}
import type { ManifestV1 } from '@proj-airi/plugin-sdk/plugin-host'

const manifest: ManifestV1 = {
  apiVersion: 'v1',
  kind: 'manifest.plugin.airi.moeru.ai',
  name: 'my-plugin',
  entrypoints: {
    default: './dist/index.mjs',
    electron: './dist/electron.mjs',
    node: './dist/node.mjs',
    web: './dist/web.mjs'
  }
}
```

## Core APIs

The SDK provides several API modules:

### Protocol APIs

Communication with the plugin host:

* **Capabilities**: Announce and wait for capabilities
* **Resources**: Manage resources and providers

### Client APIs

Access to client-side functionality:

* **Resources**: Access shared resources
* **Providers**: Query available providers

## Event-Driven Architecture

Plugins communicate through events using `@moeru/eventa`:

```typescript theme={null}
import { defineEvent, defineInvokeHandler } from '@moeru/eventa'

// Define custom event
const myEvent = defineEvent<{ message: string }>('custom:my-event')

// Emit event
channels.host.emit(myEvent, { message: 'Hello' })

// Handle event
channels.host.on(myEvent, async (event) => {
  console.log(event.payload.message)
})
```

## TypeScript Support

The SDK provides full TypeScript type definitions:

```typescript theme={null}
import type {
  Plugin,
  ContextInit,
  PluginApis,
  ManifestV1
} from '@proj-airi/plugin-sdk'
```

## Testing Plugins

Test your plugins using the plugin host:

```typescript theme={null}
import { PluginHost } from '@proj-airi/plugin-sdk/plugin-host'

const host = new PluginHost({
  runtime: 'node',
  transport: { kind: 'in-memory' }
})

const session = await host.start(manifest, {
  cwd: '/path/to/plugin'
})

console.log('Plugin phase:', session.phase) // 'ready'
```

## Plugin Examples

### Simple Tool Provider

```typescript theme={null}
export default definePlugin('weather-tool', '1.0.0', () => ({
  async init({ channels, apis }) {
    console.log('Weather tool initializing')
    return true
  },
  
  async setupModules({ channels, apis }) {
    // Register weather tool
    await apis.protocol.capabilities.markReady('tool:weather')
    
    channels.host.on('tool:weather:invoke', async (event) => {
      const { location } = event.payload
      // Fetch weather data
      return { temperature: 72, condition: 'sunny' }
    })
  }
}))
```

### LLM Provider

```typescript theme={null}
export default definePlugin('openai-provider', '1.0.0', () => ({
  async init({ channels, apis }) {
    // Wait for configuration
    channels.host.on('module:configure', async (event) => {
      const { apiKey } = event.payload.config
      // Store API key
    })
    return true
  },
  
  async setupModules({ channels, apis }) {
    // Announce LLM capability
    await apis.protocol.capabilities.markReady('llm:openai')
    
    // Handle generation requests
    channels.host.on('llm:generate', async (event) => {
      const { prompt } = event.payload
      // Call OpenAI API
      return { text: 'Generated response' }
    })
  }
}))
```

## Best Practices

<AccordionGroup>
  <Accordion title="Keep plugins focused">
    Each plugin should have a single, well-defined purpose. Split complex functionality into multiple plugins.
  </Accordion>

  <Accordion title="Handle errors gracefully">
    Return `false` from `init()` to abort initialization. Emit status events for degraded states.
  </Accordion>

  <Accordion title="Use capabilities for dependencies">
    Declare capabilities for features you provide, and wait for capabilities you depend on.
  </Accordion>

  <Accordion title="Validate configuration">
    Always validate configuration data before applying it. Provide clear error messages.
  </Accordion>

  <Accordion title="Implement cleanup">
    Clean up resources when the plugin is stopped or reloaded.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Creating Plugins" icon="code" href="/api/plugin-sdk/creating-plugins">
    Step-by-step guide to building your first plugin
  </Card>

  <Card title="Plugin API Reference" icon="book" href="/api/plugin-sdk/plugin-api">
    Complete API reference for plugin development
  </Card>
</CardGroup>
