Creating API Plugins for ElizaOS
Plugin Structure
A typical API plugin consists of:
Copy plugin-your-api/
├── src/
│ ├── index.ts # Plugin entry point
│ ├── adapter.ts # API adapter
│ ├── actions/ # API actions
│ │ ├── index.ts
│ │ └── apiActions.ts
│ ├── providers/ # Context providers
│ │ ├── index.ts
│ │ └── apiProvider.ts
│ ├── services/ # API services
│ │ ├── index.ts
│ │ └── apiService.ts
│ └── types.ts # Type definitions
├── package.json
└── tsconfig.json
Creating the Plugin
1. Initialize Plugin
Copy // src/index.ts
import { Plugin } from '@elizaos/core';
import { APIAdapter } from './adapter';
import { apiActions } from './actions';
import { apiProviders } from './providers';
import { APIService } from './services';
export default class YourAPIPlugin implements Plugin {
name = 'your-api-plugin';
version = '1.0.0';
actions = apiActions;
providers = apiProviders;
private adapter: APIAdapter;
private service: APIService;
async initialize(runtime: IAgentRuntime) {
// Initialize components
this.adapter = new APIAdapter(runtime);
this.service = new APIService(runtime);
// Register with runtime
await this.adapter.init(runtime);
await this.service.initialize();
return this;
}
}
2. Create API Adapter
Copy // src/adapter.ts
import { IAgentRuntime, Adapter } from '@elizaos/core';
export class APIAdapter implements Adapter {
constructor(private runtime: IAgentRuntime) {}
async init(runtime: IAgentRuntime) {
// Initialize adapter
await this.setupClient();
return this;
}
private async setupClient() {
// Set up API client
this.client = new APIClient({
endpoint: process.env.API_ENDPOINT,
apiKey: process.env.API_KEY
});
}
async request(method: string, params: any) {
return await this.client.request(method, params);
}
}
3. Define API Actions
Copy // src/actions/apiActions.ts
import { Action } from '@elizaos/core';
export const apiActions: Action[] = [
{
name: 'call_api',
description: 'Make an API call',
parameters: ['method', 'params'],
handler: async (runtime, message, state) => {
return await runtime.service.api.request(
message.params.method,
message.params.params
);
}
}
];
4. Create Context Providers
Copy // src/providers/apiProvider.ts
import { Provider } from '@elizaos/core';
export const apiProvider: Provider = {
name: 'api_context',
handler: async (runtime) => {
return {
apiState: await runtime.service.api.getState(),
lastResponse: await runtime.service.api.getLastResponse()
};
}
};
5. Implement API Service
Copy // src/services/apiService.ts
import { Service, ServiceType } from '@elizaos/core';
export class APIService implements Service {
serviceType = ServiceType.API;
private client: APIClient;
private lastResponse: any;
constructor(private runtime: IAgentRuntime) {}
async initialize() {
this.client = new APIClient({
endpoint: process.env.API_ENDPOINT,
apiKey: process.env.API_KEY
});
}
async request(method: string, params: any) {
try {
const result = await this.client.request(method, params);
this.lastResponse = result;
return result;
} catch (error) {
return this.handleError(error);
}
}
async getState() {
return this.client.getState();
}
async getLastResponse() {
return this.lastResponse;
}
private handleError(error: any) {
// Implement error handling
throw error;
}
}
Plugin Configuration
Configure the plugin in your agent's configuration:
Copy // agent-config.ts
import YourAPIPlugin from '@your-org/plugin-your-api';
export default {
plugins: [
{
plugin: YourAPIPlugin,
config: {
api: {
endpoint: process.env.API_ENDPOINT,
apiKey: process.env.API_KEY
}
}
}
]
};
Using the Plugin
1. Basic Usage
Copy // Initialize agent with plugin
const runtime = await createAgentRuntime({
plugins: [new YourAPIPlugin()]
});
// Use API
const result = await runtime.executeAction('call_api', {
method: 'getData',
params: { id: '123' }
});
2. Accessing API Context
Copy // Get API state
const apiState = await runtime.service.api.getState();
// Get last response
const lastResponse = await runtime.service.api.getLastResponse();
3. Error Handling
Copy try {
await runtime.executeAction('call_api', params);
} catch (error) {
// Handle error
console.error('API Error:', error);
}
Best Practices
1. Plugin Structure
Separate concerns (adapter, actions, providers)
Follow ElizaOS plugin patterns
2. API Integration
Implement proper error handling
Cache responses when appropriate
3. State Management
Implement request batching
Testing
Test your plugin:
Copy describe('YourAPIPlugin', () => {
let runtime: IAgentRuntime;
let plugin: YourAPIPlugin;
beforeEach(async () => {
runtime = await createTestRuntime();
plugin = new YourAPIPlugin();
await plugin.initialize(runtime);
});
it('should handle API calls', async () => {
const result = await runtime.executeAction('call_api', {
method: 'test',
params: {}
});
expect(result).toBeDefined();
});
it('should handle API errors', async () => {
// Test error handling
});
});
Your ElizaOS plugin now integrates your API! For more advanced features, explore the other implementation guides.