Skip to content

插件开发示例

本页面展示了如何为 XAI-SDK 开发自定义插件,包括插件架构、开发流程、最佳实践和完整示例。

📋 插件类型

提供商插件 (Provider Plugins)

连接不同的 AI 服务提供商

适配器插件 (Adapter Plugins)

适配不同的前端框架和环境

功能插件 (Feature Plugins)

扩展 SDK 的核心功能

中间件插件 (Middleware Plugins)

处理请求和响应的中间层

🏗️ 插件架构

基础插件接口

typescript
// src/types/plugin.ts
export interface XAIPlugin {
  name: string;
  version: string;
  description?: string;
  dependencies?: string[];
  
  // 插件生命周期方法
  initialize?(sdk: XAI_SDK): Promise<void> | void;
  activate?(sdk: XAI_SDK): Promise<void> | void;
  deactivate?(sdk: XAI_SDK): Promise<void> | void;
  destroy?(): Promise<void> | void;
  
  // 插件配置
  configure?(config: PluginConfig): void;
  
  // 插件能力声明
  capabilities?: PluginCapabilities;
}

export interface PluginConfig {
  [key: string]: any;
}

export interface PluginCapabilities {
  providers?: string[];
  adapters?: string[];
  features?: string[];
  middleware?: string[];
}

export abstract class BasePlugin implements XAIPlugin {
  abstract name: string;
  abstract version: string;
  description?: string;
  dependencies?: string[];
  capabilities?: PluginCapabilities;
  
  protected sdk?: XAI_SDK;
  protected config?: PluginConfig;
  
  async initialize(sdk: XAI_SDK): Promise<void> {
    this.sdk = sdk;
    console.log(`Plugin ${this.name} initialized`);
  }
  
  async activate(sdk: XAI_SDK): Promise<void> {
    console.log(`Plugin ${this.name} activated`);
  }
  
  async deactivate(sdk: XAI_SDK): Promise<void> {
    console.log(`Plugin ${this.name} deactivated`);
  }
  
  async destroy(): Promise<void> {
    this.sdk = undefined;
    this.config = undefined;
    console.log(`Plugin ${this.name} destroyed`);
  }
  
  configure(config: PluginConfig): void {
    this.config = { ...this.config, ...config };
  }
}

🚀 快速开始

创建基础插件

typescript
// src/plugins/my-custom-plugin.ts
import { BasePlugin, XAI_SDK } from 'xai-sdk';

export class MyCustomPlugin extends BasePlugin {
  name = 'my-custom-plugin';
  version = '1.0.0';
  description = '我的自定义插件示例';
  
  capabilities = {
    features: ['custom-feature']
  };
  
  async initialize(sdk: XAI_SDK): Promise<void> {
    await super.initialize(sdk);
    
    // 注册自定义方法
    sdk.registerMethod('customMethod', this.customMethod.bind(this));
    
    // 注册事件监听器
    sdk.on('beforeRequest', this.onBeforeRequest.bind(this));
    sdk.on('afterResponse', this.onAfterResponse.bind(this));
  }
  
  private async customMethod(input: string): Promise<string> {
    return `Custom processing: ${input}`;
  }
  
  private onBeforeRequest(request: any): void {
    console.log('Before request:', request);
    // 可以修改请求
    request.headers = {
      ...request.headers,
      'X-Custom-Header': 'my-plugin'
    };
  }
  
  private onAfterResponse(response: any): void {
    console.log('After response:', response);
    // 可以处理响应
  }
}

使用插件

typescript
// src/main.ts
import { XAI_SDK } from 'xai-sdk';
import { MyCustomPlugin } from './plugins/my-custom-plugin';

const sdk = new XAI_SDK();
const plugin = new MyCustomPlugin();

// 注册插件
await sdk.registerPlugin(plugin);

// 初始化 SDK
await sdk.initialize();

// 使用插件提供的方法
const result = await sdk.customMethod('Hello World');
console.log(result); // "Custom processing: Hello World"

📚 详细示例

1. 提供商插件示例

typescript
// src/plugins/custom-ai-provider.ts
import { BasePlugin, XAI_SDK, AIProvider, ChatRequest, ChatResponse } from 'xai-sdk';

export interface CustomAIConfig {
  apiKey: string;
  baseURL: string;
  model?: string;
  timeout?: number;
}

export class CustomAIProvider extends BasePlugin implements AIProvider {
  name = 'custom-ai-provider';
  version = '1.0.0';
  description = '自定义 AI 服务提供商';
  
  capabilities = {
    providers: ['custom-ai']
  };
  
  private apiKey: string = '';
  private baseURL: string = '';
  private model: string = 'default';
  private timeout: number = 30000;
  
  configure(config: CustomAIConfig): void {
    super.configure(config);
    this.apiKey = config.apiKey;
    this.baseURL = config.baseURL;
    this.model = config.model || 'default';
    this.timeout = config.timeout || 30000;
  }
  
  async initialize(sdk: XAI_SDK): Promise<void> {
    await super.initialize(sdk);
    
    if (!this.apiKey || !this.baseURL) {
      throw new Error('CustomAI provider requires apiKey and baseURL');
    }
    
    // 注册为提供商
    sdk.registerProvider('custom-ai', this);
  }
  
  async chat(request: ChatRequest): Promise<ChatResponse> {
    const response = await fetch(`${this.baseURL}/chat/completions`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.apiKey}`,
        'User-Agent': 'XAI-SDK/1.0.0'
      },
      body: JSON.stringify({
        model: this.model,
        messages: request.messages,
        max_tokens: request.maxTokens,
        temperature: request.temperature,
        stream: request.stream
      }),
      signal: AbortSignal.timeout(this.timeout)
    });
    
    if (!response.ok) {
      throw new Error(`CustomAI API error: ${response.status} ${response.statusText}`);
    }
    
    const data = await response.json();
    
    return {
      id: data.id,
      content: data.choices[0]?.message?.content || '',
      role: 'assistant',
      model: data.model,
      usage: {
        promptTokens: data.usage?.prompt_tokens || 0,
        completionTokens: data.usage?.completion_tokens || 0,
        totalTokens: data.usage?.total_tokens || 0
      },
      finishReason: data.choices[0]?.finish_reason || 'stop'
    };
  }
  
  async stream(request: ChatRequest): Promise<AsyncIterable<ChatResponse>> {
    const response = await fetch(`${this.baseURL}/chat/completions`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.apiKey}`,
        'Accept': 'text/event-stream'
      },
      body: JSON.stringify({
        model: this.model,
        messages: request.messages,
        max_tokens: request.maxTokens,
        temperature: request.temperature,
        stream: true
      })
    });
    
    if (!response.ok) {
      throw new Error(`CustomAI API error: ${response.status}`);
    }
    
    return this.parseStreamResponse(response);
  }
  
  private async* parseStreamResponse(response: Response): AsyncIterable<ChatResponse> {
    const reader = response.body?.getReader();
    if (!reader) throw new Error('No response body');
    
    const decoder = new TextDecoder();
    let buffer = '';
    
    try {
      while (true) {
        const { done, value } = await reader.read();
        if (done) break;
        
        buffer += decoder.decode(value, { stream: true });
        const lines = buffer.split('\n');
        buffer = lines.pop() || '';
        
        for (const line of lines) {
          if (line.startsWith('data: ')) {
            const data = line.slice(6);
            if (data === '[DONE]') return;
            
            try {
              const parsed = JSON.parse(data);
              const delta = parsed.choices[0]?.delta;
              
              if (delta?.content) {
                yield {
                  id: parsed.id,
                  content: delta.content,
                  role: 'assistant',
                  model: parsed.model,
                  finishReason: parsed.choices[0]?.finish_reason
                };
              }
            } catch (e) {
              console.warn('Failed to parse SSE data:', data);
            }
          }
        }
      }
    } finally {
      reader.releaseLock();
    }
  }
  
  async validateConnection(): Promise<boolean> {
    try {
      const response = await fetch(`${this.baseURL}/models`, {
        headers: {
          'Authorization': `Bearer ${this.apiKey}`
        }
      });
      return response.ok;
    } catch {
      return false;
    }
  }
}

2. 中间件插件示例

typescript
// src/plugins/logging-middleware.ts
import { BasePlugin, XAI_SDK, MiddlewareContext, MiddlewareNext } from 'xai-sdk';

export interface LoggingConfig {
  level: 'debug' | 'info' | 'warn' | 'error';
  includeRequestBody?: boolean;
  includeResponseBody?: boolean;
  maxBodyLength?: number;
}

export class LoggingMiddleware extends BasePlugin {
  name = 'logging-middleware';
  version = '1.0.0';
  description = '请求和响应日志中间件';
  
  capabilities = {
    middleware: ['request', 'response']
  };
  
  private level: string = 'info';
  private includeRequestBody: boolean = false;
  private includeResponseBody: boolean = false;
  private maxBodyLength: number = 1000;
  
  configure(config: LoggingConfig): void {
    super.configure(config);
    this.level = config.level;
    this.includeRequestBody = config.includeRequestBody ?? false;
    this.includeResponseBody = config.includeResponseBody ?? false;
    this.maxBodyLength = config.maxBodyLength ?? 1000;
  }
  
  async initialize(sdk: XAI_SDK): Promise<void> {
    await super.initialize(sdk);
    
    // 注册请求中间件
    sdk.use('request', this.requestMiddleware.bind(this));
    
    // 注册响应中间件
    sdk.use('response', this.responseMiddleware.bind(this));
  }
  
  private async requestMiddleware(context: MiddlewareContext, next: MiddlewareNext): Promise<void> {
    const startTime = Date.now();
    context.metadata = { ...context.metadata, startTime };
    
    this.log('info', 'Request started', {
      method: context.request.method,
      url: context.request.url,
      headers: this.sanitizeHeaders(context.request.headers),
      body: this.includeRequestBody ? this.truncateBody(context.request.body) : undefined
    });
    
    try {
      await next();
    } catch (error) {
      this.log('error', 'Request failed', {
        error: error instanceof Error ? error.message : String(error),
        duration: Date.now() - startTime
      });
      throw error;
    }
  }
  
  private async responseMiddleware(context: MiddlewareContext, next: MiddlewareNext): Promise<void> {
    await next();
    
    const duration = Date.now() - (context.metadata?.startTime || 0);
    
    this.log('info', 'Response received', {
      status: context.response?.status,
      headers: this.sanitizeHeaders(context.response?.headers),
      body: this.includeResponseBody ? this.truncateBody(context.response?.body) : undefined,
      duration: `${duration}ms`
    });
  }
  
  private sanitizeHeaders(headers: Record<string, string> = {}): Record<string, string> {
    const sanitized = { ...headers };
    
    // 隐藏敏感信息
    const sensitiveKeys = ['authorization', 'x-api-key', 'cookie'];
    for (const key of sensitiveKeys) {
      if (sanitized[key.toLowerCase()]) {
        sanitized[key.toLowerCase()] = '[REDACTED]';
      }
    }
    
    return sanitized;
  }
  
  private truncateBody(body: any): string {
    if (!body) return '';
    
    const str = typeof body === 'string' ? body : JSON.stringify(body);
    return str.length > this.maxBodyLength 
      ? str.substring(0, this.maxBodyLength) + '...[truncated]'
      : str;
  }
  
  private log(level: string, message: string, data?: any): void {
    const timestamp = new Date().toISOString();
    const logEntry = {
      timestamp,
      level,
      plugin: this.name,
      message,
      ...data
    };
    
    switch (level) {
      case 'debug':
        console.debug('[XAI-SDK]', logEntry);
        break;
      case 'info':
        console.info('[XAI-SDK]', logEntry);
        break;
      case 'warn':
        console.warn('[XAI-SDK]', logEntry);
        break;
      case 'error':
        console.error('[XAI-SDK]', logEntry);
        break;
    }
  }
}

3. 缓存插件示例

typescript
// src/plugins/cache-plugin.ts
import { BasePlugin, XAI_SDK, ChatRequest, ChatResponse } from 'xai-sdk';

export interface CacheConfig {
  ttl?: number; // 缓存时间(毫秒)
  maxSize?: number; // 最大缓存条目数
  storage?: 'memory' | 'localStorage' | 'sessionStorage';
  keyGenerator?: (request: ChatRequest) => string;
}

interface CacheEntry {
  data: ChatResponse;
  timestamp: number;
  ttl: number;
}

export class CachePlugin extends BasePlugin {
  name = 'cache-plugin';
  version = '1.0.0';
  description = '响应缓存插件';
  
  capabilities = {
    features: ['caching']
  };
  
  private ttl: number = 5 * 60 * 1000; // 5分钟
  private maxSize: number = 100;
  private storage: 'memory' | 'localStorage' | 'sessionStorage' = 'memory';
  private keyGenerator: (request: ChatRequest) => string;
  private memoryCache = new Map<string, CacheEntry>();
  
  constructor() {
    super();
    this.keyGenerator = this.defaultKeyGenerator;
  }
  
  configure(config: CacheConfig): void {
    super.configure(config);
    this.ttl = config.ttl ?? this.ttl;
    this.maxSize = config.maxSize ?? this.maxSize;
    this.storage = config.storage ?? this.storage;
    this.keyGenerator = config.keyGenerator ?? this.keyGenerator;
  }
  
  async initialize(sdk: XAI_SDK): Promise<void> {
    await super.initialize(sdk);
    
    // 拦截 chat 方法
    const originalChat = sdk.chat.bind(sdk);
    sdk.chat = this.createCachedMethod(originalChat);
    
    // 定期清理过期缓存
    setInterval(() => this.cleanupExpiredEntries(), 60000); // 每分钟清理一次
  }
  
  private createCachedMethod(originalMethod: (request: ChatRequest) => Promise<ChatResponse>) {
    return async (request: ChatRequest): Promise<ChatResponse> => {
      // 流式请求不缓存
      if (request.stream) {
        return originalMethod(request);
      }
      
      const cacheKey = this.keyGenerator(request);
      
      // 尝试从缓存获取
      const cached = this.getFromCache(cacheKey);
      if (cached) {
        console.log(`Cache hit for key: ${cacheKey}`);
        return { ...cached, fromCache: true };
      }
      
      // 缓存未命中,调用原方法
      console.log(`Cache miss for key: ${cacheKey}`);
      const response = await originalMethod(request);
      
      // 存储到缓存
      this.setToCache(cacheKey, response);
      
      return response;
    };
  }
  
  private defaultKeyGenerator(request: ChatRequest): string {
    const key = {
      messages: request.messages,
      maxTokens: request.maxTokens,
      temperature: request.temperature,
      model: request.model
    };
    return this.hashObject(key);
  }
  
  private hashObject(obj: any): string {
    const str = JSON.stringify(obj, Object.keys(obj).sort());
    let hash = 0;
    for (let i = 0; i < str.length; i++) {
      const char = str.charCodeAt(i);
      hash = ((hash << 5) - hash) + char;
      hash = hash & hash; // 转换为32位整数
    }
    return hash.toString(36);
  }
  
  private getFromCache(key: string): ChatResponse | null {
    switch (this.storage) {
      case 'memory':
        return this.getFromMemoryCache(key);
      case 'localStorage':
        return this.getFromWebStorage(localStorage, key);
      case 'sessionStorage':
        return this.getFromWebStorage(sessionStorage, key);
      default:
        return null;
    }
  }
  
  private setToCache(key: string, data: ChatResponse): void {
    const entry: CacheEntry = {
      data,
      timestamp: Date.now(),
      ttl: this.ttl
    };
    
    switch (this.storage) {
      case 'memory':
        this.setToMemoryCache(key, entry);
        break;
      case 'localStorage':
        this.setToWebStorage(localStorage, key, entry);
        break;
      case 'sessionStorage':
        this.setToWebStorage(sessionStorage, key, entry);
        break;
    }
  }
  
  private getFromMemoryCache(key: string): ChatResponse | null {
    const entry = this.memoryCache.get(key);
    if (!entry) return null;
    
    if (Date.now() - entry.timestamp > entry.ttl) {
      this.memoryCache.delete(key);
      return null;
    }
    
    return entry.data;
  }
  
  private setToMemoryCache(key: string, entry: CacheEntry): void {
    // 检查缓存大小限制
    if (this.memoryCache.size >= this.maxSize) {
      // 删除最旧的条目
      const oldestKey = this.memoryCache.keys().next().value;
      this.memoryCache.delete(oldestKey);
    }
    
    this.memoryCache.set(key, entry);
  }
  
  private getFromWebStorage(storage: Storage, key: string): ChatResponse | null {
    try {
      const item = storage.getItem(`xai-cache-${key}`);
      if (!item) return null;
      
      const entry: CacheEntry = JSON.parse(item);
      if (Date.now() - entry.timestamp > entry.ttl) {
        storage.removeItem(`xai-cache-${key}`);
        return null;
      }
      
      return entry.data;
    } catch {
      return null;
    }
  }
  
  private setToWebStorage(storage: Storage, key: string, entry: CacheEntry): void {
    try {
      storage.setItem(`xai-cache-${key}`, JSON.stringify(entry));
    } catch (error) {
      console.warn('Failed to store cache entry:', error);
    }
  }
  
  private cleanupExpiredEntries(): void {
    const now = Date.now();
    
    // 清理内存缓存
    for (const [key, entry] of this.memoryCache.entries()) {
      if (now - entry.timestamp > entry.ttl) {
        this.memoryCache.delete(key);
      }
    }
    
    // 清理 Web Storage(仅在浏览器环境)
    if (typeof window !== 'undefined') {
      this.cleanupWebStorage(localStorage);
      this.cleanupWebStorage(sessionStorage);
    }
  }
  
  private cleanupWebStorage(storage: Storage): void {
    const keysToRemove: string[] = [];
    
    for (let i = 0; i < storage.length; i++) {
      const key = storage.key(i);
      if (key?.startsWith('xai-cache-')) {
        try {
          const item = storage.getItem(key);
          if (item) {
            const entry: CacheEntry = JSON.parse(item);
            if (Date.now() - entry.timestamp > entry.ttl) {
              keysToRemove.push(key);
            }
          }
        } catch {
          keysToRemove.push(key);
        }
      }
    }
    
    keysToRemove.forEach(key => storage.removeItem(key));
  }
  
  // 公共方法:清空缓存
  clearCache(): void {
    this.memoryCache.clear();
    
    if (typeof window !== 'undefined') {
      // 清空 localStorage 中的缓存
      const keysToRemove: string[] = [];
      for (let i = 0; i < localStorage.length; i++) {
        const key = localStorage.key(i);
        if (key?.startsWith('xai-cache-')) {
          keysToRemove.push(key);
        }
      }
      keysToRemove.forEach(key => localStorage.removeItem(key));
      
      // 清空 sessionStorage 中的缓存
      keysToRemove.length = 0;
      for (let i = 0; i < sessionStorage.length; i++) {
        const key = sessionStorage.key(i);
        if (key?.startsWith('xai-cache-')) {
          keysToRemove.push(key);
        }
      }
      keysToRemove.forEach(key => sessionStorage.removeItem(key));
    }
  }
  
  // 公共方法:获取缓存统计
  getCacheStats(): { size: number; hitRate: number } {
    // 这里可以实现更详细的统计逻辑
    return {
      size: this.memoryCache.size,
      hitRate: 0 // 需要实现命中率统计
    };
  }
}

🧪 插件测试

单元测试示例

typescript
// src/plugins/__tests__/cache-plugin.test.ts
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { CachePlugin } from '../cache-plugin';
import { XAI_SDK } from 'xai-sdk';

describe('CachePlugin', () => {
  let plugin: CachePlugin;
  let sdk: XAI_SDK;
  let mockChat: ReturnType<typeof vi.fn>;
  
  beforeEach(() => {
    plugin = new CachePlugin();
    sdk = new XAI_SDK();
    mockChat = vi.fn();
    sdk.chat = mockChat;
  });
  
  afterEach(() => {
    plugin.clearCache();
  });
  
  it('should cache responses', async () => {
    const request = {
      messages: [{ role: 'user', content: 'Hello' }],
      maxTokens: 100,
      temperature: 0.7
    };
    
    const response = {
      id: 'test-1',
      content: 'Hello there!',
      role: 'assistant'
    };
    
    mockChat.mockResolvedValue(response);
    
    await plugin.initialize(sdk);
    
    // 第一次调用
    const result1 = await sdk.chat(request);
    expect(result1).toEqual(response);
    expect(mockChat).toHaveBeenCalledTimes(1);
    
    // 第二次调用应该从缓存返回
    const result2 = await sdk.chat(request);
    expect(result2).toEqual({ ...response, fromCache: true });
    expect(mockChat).toHaveBeenCalledTimes(1); // 没有再次调用
  });
  
  it('should not cache stream requests', async () => {
    const request = {
      messages: [{ role: 'user', content: 'Hello' }],
      stream: true
    };
    
    const response = {
      id: 'test-1',
      content: 'Hello there!',
      role: 'assistant'
    };
    
    mockChat.mockResolvedValue(response);
    
    await plugin.initialize(sdk);
    
    await sdk.chat(request);
    await sdk.chat(request);
    
    expect(mockChat).toHaveBeenCalledTimes(2);
  });
  
  it('should expire cached entries', async () => {
    plugin.configure({ ttl: 100 }); // 100ms TTL
    
    const request = {
      messages: [{ role: 'user', content: 'Hello' }],
      maxTokens: 100
    };
    
    const response = {
      id: 'test-1',
      content: 'Hello there!',
      role: 'assistant'
    };
    
    mockChat.mockResolvedValue(response);
    
    await plugin.initialize(sdk);
    
    // 第一次调用
    await sdk.chat(request);
    expect(mockChat).toHaveBeenCalledTimes(1);
    
    // 等待缓存过期
    await new Promise(resolve => setTimeout(resolve, 150));
    
    // 第二次调用应该重新请求
    await sdk.chat(request);
    expect(mockChat).toHaveBeenCalledTimes(2);
  });
});

集成测试示例

typescript
// src/plugins/__tests__/plugin-integration.test.ts
import { describe, it, expect, beforeEach } from 'vitest';
import { XAI_SDK } from 'xai-sdk';
import { CachePlugin } from '../cache-plugin';
import { LoggingMiddleware } from '../logging-middleware';
import { CustomAIProvider } from '../custom-ai-provider';

describe('Plugin Integration', () => {
  let sdk: XAI_SDK;
  
  beforeEach(() => {
    sdk = new XAI_SDK();
  });
  
  it('should work with multiple plugins', async () => {
    const cachePlugin = new CachePlugin();
    const loggingPlugin = new LoggingMiddleware();
    const providerPlugin = new CustomAIProvider();
    
    // 配置插件
    cachePlugin.configure({ ttl: 60000 });
    loggingPlugin.configure({ level: 'info' });
    providerPlugin.configure({
      apiKey: 'test-key',
      baseURL: 'https://api.example.com'
    });
    
    // 注册插件
    await sdk.registerPlugin(cachePlugin);
    await sdk.registerPlugin(loggingPlugin);
    await sdk.registerPlugin(providerPlugin);
    
    // 初始化 SDK
    await sdk.initialize();
    
    // 验证插件已注册
    expect(sdk.getRegisteredPlugins()).toHaveLength(3);
    expect(sdk.hasPlugin('cache-plugin')).toBe(true);
    expect(sdk.hasPlugin('logging-middleware')).toBe(true);
    expect(sdk.hasPlugin('custom-ai-provider')).toBe(true);
  });
  
  it('should handle plugin dependencies', async () => {
    // 创建有依赖关系的插件
    class DependentPlugin extends BasePlugin {
      name = 'dependent-plugin';
      version = '1.0.0';
      dependencies = ['cache-plugin'];
      
      async initialize(sdk: XAI_SDK): Promise<void> {
        if (!sdk.hasPlugin('cache-plugin')) {
          throw new Error('Required plugin cache-plugin not found');
        }
        await super.initialize(sdk);
      }
    }
    
    const cachePlugin = new CachePlugin();
    const dependentPlugin = new DependentPlugin();
    
    await sdk.registerPlugin(cachePlugin);
    await sdk.registerPlugin(dependentPlugin);
    
    await expect(sdk.initialize()).resolves.not.toThrow();
  });
});

📖 最佳实践

1. 插件设计原则

typescript
// ✅ 好的插件设计
export class WellDesignedPlugin extends BasePlugin {
  name = 'well-designed-plugin';
  version = '1.0.0';
  
  // 明确声明能力
  capabilities = {
    features: ['feature-a', 'feature-b']
  };
  
  // 提供配置验证
  configure(config: PluginConfig): void {
    this.validateConfig(config);
    super.configure(config);
  }
  
  private validateConfig(config: PluginConfig): void {
    if (!config.requiredField) {
      throw new Error('requiredField is required');
    }
  }
  
  // 优雅的错误处理
  async initialize(sdk: XAI_SDK): Promise<void> {
    try {
      await super.initialize(sdk);
      await this.setupPlugin();
    } catch (error) {
      console.error(`Failed to initialize ${this.name}:`, error);
      throw error;
    }
  }
  
  private async setupPlugin(): Promise<void> {
    // 插件特定的初始化逻辑
  }
  
  // 清理资源
  async destroy(): Promise<void> {
    await this.cleanup();
    await super.destroy();
  }
  
  private async cleanup(): Promise<void> {
    // 清理插件资源
  }
}

2. 错误处理

typescript
export class RobustPlugin extends BasePlugin {
  name = 'robust-plugin';
  version = '1.0.0';
  
  async initialize(sdk: XAI_SDK): Promise<void> {
    try {
      await super.initialize(sdk);
      
      // 注册错误处理器
      sdk.on('error', this.handleError.bind(this));
      
    } catch (error) {
      // 记录错误但不阻止其他插件
      console.error(`Plugin ${this.name} initialization failed:`, error);
      
      // 可以选择性地重新抛出错误
      if (this.isRequired) {
        throw error;
      }
    }
  }
  
  private handleError(error: Error, context?: any): void {
    console.error(`Error in ${this.name}:`, error, context);
    
    // 可以实现错误恢复逻辑
    this.attemptRecovery(error);
  }
  
  private attemptRecovery(error: Error): void {
    // 实现错误恢复逻辑
  }
}

3. 性能优化

typescript
export class OptimizedPlugin extends BasePlugin {
  name = 'optimized-plugin';
  version = '1.0.0';
  
  private cache = new Map();
  private debounceTimers = new Map();
  
  // 使用防抖优化频繁调用
  debounce(key: string, fn: Function, delay: number): void {
    const existingTimer = this.debounceTimers.get(key);
    if (existingTimer) {
      clearTimeout(existingTimer);
    }
    
    const timer = setTimeout(() => {
      fn();
      this.debounceTimers.delete(key);
    }, delay);
    
    this.debounceTimers.set(key, timer);
  }
  
  // 使用缓存避免重复计算
  async expensiveOperation(input: string): Promise<string> {
    if (this.cache.has(input)) {
      return this.cache.get(input);
    }
    
    const result = await this.performExpensiveOperation(input);
    this.cache.set(input, result);
    
    return result;
  }
  
  private async performExpensiveOperation(input: string): Promise<string> {
    // 执行昂贵的操作
    return `processed: ${input}`;
  }
  
  async destroy(): Promise<void> {
    // 清理定时器
    for (const timer of this.debounceTimers.values()) {
      clearTimeout(timer);
    }
    this.debounceTimers.clear();
    
    // 清理缓存
    this.cache.clear();
    
    await super.destroy();
  }
}

📦 插件发布

package.json 配置

json
{
  "name": "@my-org/xai-sdk-plugin-example",
  "version": "1.0.0",
  "description": "Example plugin for XAI-SDK",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "files": [
    "dist",
    "README.md",
    "LICENSE"
  ],
  "keywords": [
    "xai-sdk",
    "plugin",
    "ai",
    "machine-learning"
  ],
  "peerDependencies": {
    "xai-sdk": "^1.0.0"
  },
  "devDependencies": {
    "xai-sdk": "^1.0.0",
    "typescript": "^5.0.0",
    "vitest": "^1.0.0"
  },
  "scripts": {
    "build": "tsc",
    "test": "vitest",
    "prepublishOnly": "npm run build && npm test"
  }
}

TypeScript 配置

json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "node",
    "declaration": true,
    "outDir": "dist",
    "rootDir": "src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist", "**/*.test.ts"]
}

📝 相关资源


💡 提示: 插件开发需要深入理解 XAI-SDK 的架构和生命周期。建议先从简单的功能插件开始,逐步掌握更复杂的提供商和中间件插件开发。

Released under the MIT License.