Skip to content

插件系统API参考

本文档详细介绍了XAI-SDK插件系统的API接口,包括插件开发所需的所有接口和类型定义。

Plugin 接口

所有插件都必须实现的基础接口。

typescript
interface Plugin {
  // 基本信息
  readonly name: string
  readonly version: string
  readonly metadata: PluginMetadata
  
  // 依赖和环境
  dependencies?: PluginDependency[]
  supportedEnvironments?: Environment[]
  requiredSDKVersion?: string
  
  // 功能定义
  tools?: Record<string, ToolDefinition>
  adapters?: Record<string, AdapterDefinition>
  providers?: Record<string, ProviderDefinition>
  
  // 生命周期方法
  initialize(sdk?: XAISDKInstance): Promise<boolean>
  enable?(): Promise<boolean>
  disable?(): Promise<boolean>
  destroy(): Promise<boolean>
  
  // 状态管理
  getState(): PluginState
  isInitialized(): boolean
}

基本属性

name

插件的唯一标识符。

typescript
readonly name: string

要求:

  • 必须唯一
  • 只能包含字母、数字、连字符和下划线
  • 建议使用kebab-case格式

示例:

typescript
readonly name = 'file-operations'

version

插件版本号,遵循语义化版本规范。

typescript
readonly version: string

示例:

typescript
readonly version = '1.2.3'

metadata

插件元数据信息。

typescript
readonly metadata: PluginMetadata

PluginMetadata接口:

typescript
interface PluginMetadata {
  description: string        // 插件描述
  author: string            // 作者信息
  homepage?: string         // 主页URL
  repository?: string       // 仓库URL
  license?: string          // 许可证
  tags?: string[]          // 标签
  keywords?: string[]      // 关键词
  icon?: string            // 图标URL
  screenshots?: string[]   // 截图URL列表
}

示例:

typescript
readonly metadata: PluginMetadata = {
  description: '提供文件操作相关工具',
  author: 'XAI-SDK Team <team@xai-sdk.com>',
  homepage: 'https://github.com/xai-sdk/file-operations-plugin',
  repository: 'https://github.com/xai-sdk/file-operations-plugin',
  license: 'MIT',
  tags: ['file', 'io', 'utility'],
  keywords: ['file', 'read', 'write', 'operations']
}

依赖和环境

dependencies

插件依赖列表。

typescript
dependencies?: PluginDependency[]

PluginDependency接口:

typescript
interface PluginDependency {
  name: string              // 依赖插件名称
  version?: string          // 版本要求
  optional?: boolean        // 是否可选
  reason?: string          // 依赖原因说明
}

示例:

typescript
dependencies = [
  {
    name: 'http-client',
    version: '^1.0.0',
    optional: false,
    reason: '需要HTTP客户端进行网络请求'
  },
  {
    name: 'cache-manager',
    version: '>=2.0.0',
    optional: true,
    reason: '可选的缓存功能'
  }
]

supportedEnvironments

支持的运行环境列表。

typescript
supportedEnvironments?: Environment[]

Environment类型:

typescript
type Environment = 'node' | 'browser' | 'cli' | 'electron' | 'react-native'

示例:

typescript
supportedEnvironments = ['node', 'electron']

requiredSDKVersion

所需的SDK最低版本。

typescript
requiredSDKVersion?: string

示例:

typescript
requiredSDKVersion = '>=1.0.0'

功能定义

tools

插件提供的工具定义。

typescript
tools?: Record<string, ToolDefinition>

ToolDefinition接口:

typescript
interface ToolDefinition {
  name: string
  description: string
  parameters: Record<string, ParameterDefinition>
  handler: ToolHandler
  examples?: ToolExample[]
  category?: string
  tags?: string[]
}

type ToolHandler = (params: Record<string, any>) => Promise<any>

interface ParameterDefinition {
  type: 'string' | 'number' | 'boolean' | 'object' | 'array'
  required: boolean
  description?: string
  default?: any
  enum?: any[]
  pattern?: string
  minimum?: number
  maximum?: number
  items?: ParameterDefinition  // 用于array类型
  properties?: Record<string, ParameterDefinition>  // 用于object类型
}

interface ToolExample {
  name: string
  description: string
  input: Record<string, any>
  output: any
}

示例:

typescript
tools = {
  'read-file': {
    name: 'read-file',
    description: '读取文件内容',
    category: 'file-operations',
    tags: ['file', 'read', 'io'],
    parameters: {
      path: {
        type: 'string',
        required: true,
        description: '要读取的文件路径',
        pattern: '^[^<>:"|?*]+$'
      },
      encoding: {
        type: 'string',
        required: false,
        description: '文件编码格式',
        default: 'utf-8',
        enum: ['utf-8', 'ascii', 'base64', 'hex']
      }
    },
    handler: this.readFile.bind(this),
    examples: [
      {
        name: '读取JSON文件',
        description: '读取package.json文件内容',
        input: { path: './package.json' },
        output: { success: true, content: '{ "name": "my-app" }' }
      }
    ]
  }
}

生命周期方法

initialize()

插件初始化方法,在插件注册时调用。

typescript
initialize(sdk?: XAISDKInstance): Promise<boolean>

参数:

  • sdk: SDK实例引用

返回值:

  • true: 初始化成功
  • false: 初始化失败

示例:

typescript
async initialize(sdk?: XAISDKInstance): Promise<boolean> {
  try {
    this.sdk = sdk
    
    // 检查环境
    if (!this.validateEnvironment()) {
      throw new Error('不支持的运行环境')
    }
    
    // 初始化资源
    await this.initializeResources()
    
    this.log('info', '插件初始化成功')
    return true
  } catch (error) {
    this.log('error', `插件初始化失败: ${error.message}`)
    return false
  }
}

enable()

启用插件,在初始化成功后调用。

typescript
enable?(): Promise<boolean>

示例:

typescript
async enable(): Promise<boolean> {
  try {
    // 启动服务
    await this.startServices()
    
    // 注册事件监听器
    this.registerEventListeners()
    
    this.log('info', '插件已启用')
    return true
  } catch (error) {
    this.log('error', `插件启用失败: ${error.message}`)
    return false
  }
}

disable()

禁用插件。

typescript
disable?(): Promise<boolean>

示例:

typescript
async disable(): Promise<boolean> {
  try {
    // 停止服务
    await this.stopServices()
    
    // 移除事件监听器
    this.removeEventListeners()
    
    this.log('info', '插件已禁用')
    return true
  } catch (error) {
    this.log('error', `插件禁用失败: ${error.message}`)
    return false
  }
}

destroy()

销毁插件,清理所有资源。

typescript
destroy(): Promise<boolean>

示例:

typescript
async destroy(): Promise<boolean> {
  try {
    // 清理资源
    await this.cleanup()
    
    // 重置状态
    this.resetState()
    
    this.log('info', '插件已销毁')
    return true
  } catch (error) {
    this.log('error', `插件销毁失败: ${error.message}`)
    return false
  }
}

BasePlugin 基类

推荐继承的插件基类,提供了常用的功能实现。

typescript
abstract class BasePlugin implements Plugin {
  // 抽象属性(子类必须实现)
  abstract readonly name: string
  abstract readonly version: string
  abstract readonly metadata: PluginMetadata
  
  // 可选属性
  dependencies?: PluginDependency[]
  supportedEnvironments?: Environment[]
  requiredSDKVersion?: string
  tools?: Record<string, ToolDefinition>
  adapters?: Record<string, AdapterDefinition>
  providers?: Record<string, ProviderDefinition>
  
  // 内部状态
  protected sdk?: XAISDKInstance
  protected state: PluginState = PluginState.UNINITIALIZED
  protected config: Record<string, any> = {}
  
  // 生命周期钩子(子类可重写)
  protected async onInitialize(): Promise<void> {}
  protected async onEnable(): Promise<void> {}
  protected async onDisable(): Promise<void> {}
  protected async onDestroy(): Promise<void> {}
  
  // 工具方法
  protected log(level: LogLevel, message: string, ...args: any[]): void
  protected getSDK(): XAISDKInstance | null
  protected validateEnvironment(): boolean
  protected getConfig<T>(key: string, defaultValue?: T): T
  protected setConfig(key: string, value: any): void
  protected emit(event: string, ...args: any[]): void
}

状态管理

PluginState 枚举

typescript
enum PluginState {
  UNINITIALIZED = 'uninitialized',
  INITIALIZING = 'initializing',
  INITIALIZED = 'initialized',
  ENABLING = 'enabling',
  ENABLED = 'enabled',
  DISABLING = 'disabling',
  DISABLED = 'disabled',
  DESTROYING = 'destroying',
  DESTROYED = 'destroyed',
  ERROR = 'error'
}

getState()

获取插件当前状态。

typescript
getState(): PluginState

isInitialized()

检查插件是否已初始化。

typescript
isInitialized(): boolean

工具方法

log()

记录日志信息。

typescript
protected log(level: LogLevel, message: string, ...args: any[]): void

LogLevel类型:

typescript
type LogLevel = 'debug' | 'info' | 'warn' | 'error'

示例:

typescript
this.log('info', '开始处理文件', { path: '/path/to/file' })
this.log('error', '文件处理失败', error)

getSDK()

获取SDK实例引用。

typescript
protected getSDK(): XAISDKInstance | null

示例:

typescript
const sdk = this.getSDK()
if (sdk) {
  const tools = sdk.getAvailableTools()
}

validateEnvironment()

验证当前运行环境是否受支持。

typescript
protected validateEnvironment(): boolean

示例:

typescript
protected validateEnvironment(): boolean {
  if (!this.supportedEnvironments) {
    return true // 未指定环境要求,默认支持所有环境
  }
  
  const currentEnv = this.getSDK()?.getConfig('environment')
  return this.supportedEnvironments.includes(currentEnv)
}

getConfig() / setConfig()

配置管理方法。

typescript
protected getConfig<T>(key: string, defaultValue?: T): T
protected setConfig(key: string, value: any): void

示例:

typescript
// 获取配置
const timeout = this.getConfig('timeout', 5000)
const debug = this.getConfig<boolean>('debug', false)

// 设置配置
this.setConfig('timeout', 10000)
this.setConfig('debug', true)

emit()

触发事件。

typescript
protected emit(event: string, ...args: any[]): void

示例:

typescript
// 触发自定义事件
this.emit('file:processed', { path: '/path/to/file', size: 1024 })
this.emit('error', new Error('处理失败'))

工具开发

ToolHandler 类型

工具处理函数的类型定义。

typescript
type ToolHandler = (params: Record<string, any>) => Promise<any>

工具开发示例

typescript
class FileOperationsPlugin extends BasePlugin {
  readonly name = 'file-operations'
  readonly version = '1.0.0'
  readonly metadata = {
    description: '文件操作工具集',
    author: 'XAI-SDK Team'
  }
  
  tools = {
    'read-file': {
      name: 'read-file',
      description: '读取文件内容',
      parameters: {
        path: { type: 'string', required: true, description: '文件路径' }
      },
      handler: this.readFile.bind(this)
    }
  }
  
  private async readFile(params: { path: string }): Promise<any> {
    try {
      // 参数验证
      this.validateParameters(params, this.tools['read-file'].parameters)
      
      // 执行操作
      const content = await fs.readFile(params.path, 'utf-8')
      
      // 记录日志
      this.log('info', `成功读取文件: ${params.path}`)
      
      // 触发事件
      this.emit('file:read', { path: params.path, size: content.length })
      
      return {
        success: true,
        content,
        size: content.length,
        encoding: 'utf-8'
      }
    } catch (error) {
      this.log('error', `读取文件失败: ${error.message}`, { path: params.path })
      
      return {
        success: false,
        error: error.message,
        code: 'FILE_READ_ERROR'
      }
    }
  }
  
  private validateParameters(params: any, schema: Record<string, ParameterDefinition>): void {
    for (const [key, definition] of Object.entries(schema)) {
      if (definition.required && !(key in params)) {
        throw new Error(`缺少必需参数: ${key}`)
      }
      
      if (key in params) {
        const value = params[key]
        const type = typeof value
        
        if (definition.type === 'string' && type !== 'string') {
          throw new Error(`参数 ${key} 必须是字符串类型`)
        }
        
        if (definition.pattern && typeof value === 'string') {
          const regex = new RegExp(definition.pattern)
          if (!regex.test(value)) {
            throw new Error(`参数 ${key} 格式不正确`)
          }
        }
      }
    }
  }
}

适配器开发

AdapterDefinition 接口

typescript
interface AdapterDefinition {
  name: string
  description: string
  targetFramework: string
  version: string
  adapter: AdapterHandler
  examples?: AdapterExample[]
}

type AdapterHandler = (context: AdapterContext) => Promise<any>

interface AdapterContext {
  framework: string
  version: string
  environment: Environment
  options: Record<string, any>
}

interface AdapterExample {
  name: string
  description: string
  code: string
  framework: string
}

适配器开发示例

typescript
class ReactAdapterPlugin extends BasePlugin {
  readonly name = 'react-adapter'
  readonly version = '1.0.0'
  readonly metadata = {
    description: 'React框架适配器',
    author: 'XAI-SDK Team'
  }
  
  adapters = {
    'react-hooks': {
      name: 'react-hooks',
      description: 'React Hooks适配器',
      targetFramework: 'react',
      version: '>=16.8.0',
      adapter: this.createReactHooks.bind(this),
      examples: [
        {
          name: 'useXAI Hook',
          description: '在React组件中使用XAI-SDK',
          framework: 'react',
          code: `
const { chat, loading, error } = useXAI({
  provider: 'openai',
  apiKey: 'your-key'
})
          `
        }
      ]
    }
  }
  
  private async createReactHooks(context: AdapterContext): Promise<any> {
    // 返回React Hooks实现
    return {
      useXAI: (options: any) => {
        // React Hook实现
      },
      useTools: (toolNames: string[]) => {
        // 工具Hook实现
      }
    }
  }
}

提供商开发

ProviderDefinition 接口

typescript
interface ProviderDefinition {
  name: string
  description: string
  version: string
  provider: ProviderHandler
  models?: ModelDefinition[]
  capabilities?: ProviderCapability[]
}

type ProviderHandler = (context: ProviderContext) => Promise<ProviderInstance>

interface ProviderContext {
  apiKey?: string
  baseURL?: string
  options: Record<string, any>
}

interface ProviderInstance {
  chat(messages: ChatMessage[], options?: ChatOptions): Promise<ChatResponse>
  streamChat?(messages: ChatMessage[], options?: ChatOptions): AsyncIterable<ChatStreamChunk>
  getModels?(): Promise<ModelDefinition[]>
}

interface ModelDefinition {
  id: string
  name: string
  description?: string
  maxTokens?: number
  supportsFunctions?: boolean
  supportsStreaming?: boolean
}

type ProviderCapability = 'chat' | 'streaming' | 'functions' | 'embeddings' | 'images'

提供商开发示例

typescript
class OllamaProviderPlugin extends BasePlugin {
  readonly name = 'ollama-provider'
  readonly version = '1.0.0'
  readonly metadata = {
    description: 'Ollama本地AI提供商',
    author: 'XAI-SDK Team'
  }
  
  providers = {
    'ollama': {
      name: 'ollama',
      description: 'Ollama本地AI服务',
      version: '1.0.0',
      provider: this.createOllamaProvider.bind(this),
      capabilities: ['chat', 'streaming'],
      models: [
        {
          id: 'llama2',
          name: 'Llama 2',
          description: 'Meta的Llama 2模型',
          maxTokens: 4096,
          supportsFunctions: false,
          supportsStreaming: true
        }
      ]
    }
  }
  
  private async createOllamaProvider(context: ProviderContext): Promise<ProviderInstance> {
    const baseURL = context.baseURL || 'http://localhost:11434'
    
    return {
      async chat(messages: ChatMessage[], options?: ChatOptions): Promise<ChatResponse> {
        // 实现Ollama聊天API调用
        const response = await fetch(`${baseURL}/api/chat`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            model: options?.model || 'llama2',
            messages,
            stream: false
          })
        })
        
        const data = await response.json()
        
        return {
          content: data.message.content,
          role: 'assistant',
          usage: {
            promptTokens: data.prompt_eval_count || 0,
            completionTokens: data.eval_count || 0,
            totalTokens: (data.prompt_eval_count || 0) + (data.eval_count || 0)
          }
        }
      },
      
      async *streamChat(messages: ChatMessage[], options?: ChatOptions): AsyncIterable<ChatStreamChunk> {
        // 实现流式聊天
        const response = await fetch(`${baseURL}/api/chat`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            model: options?.model || 'llama2',
            messages,
            stream: true
          })
        })
        
        const reader = response.body?.getReader()
        if (!reader) return
        
        while (true) {
          const { done, value } = await reader.read()
          if (done) break
          
          const chunk = new TextDecoder().decode(value)
          const lines = chunk.split('\n').filter(line => line.trim())
          
          for (const line of lines) {
            try {
              const data = JSON.parse(line)
              if (data.message?.content) {
                yield {
                  content: data.message.content,
                  role: 'assistant',
                  done: data.done || false
                }
              }
            } catch (error) {
              // 忽略解析错误
            }
          }
        }
      }
    }
  }
}

错误处理

PluginError 类

typescript
class PluginError extends Error {
  code: string
  plugin: string
  details?: any
  
  constructor(message: string, code: string, plugin: string, details?: any) {
    super(message)
    this.name = 'PluginError'
    this.code = code
    this.plugin = plugin
    this.details = details
  }
}

错误代码:

  • PLUGIN_INIT_FAILED - 插件初始化失败
  • PLUGIN_ENABLE_FAILED - 插件启用失败
  • PLUGIN_DISABLE_FAILED - 插件禁用失败
  • PLUGIN_DESTROY_FAILED - 插件销毁失败
  • TOOL_EXECUTION_FAILED - 工具执行失败
  • INVALID_PARAMETERS - 参数无效
  • UNSUPPORTED_ENVIRONMENT - 不支持的环境
  • DEPENDENCY_NOT_FOUND - 依赖未找到

错误处理示例

typescript
class MyPlugin extends BasePlugin {
  private async myTool(params: any): Promise<any> {
    try {
      // 工具逻辑
      return { success: true, result: 'ok' }
    } catch (error) {
      // 记录错误
      this.log('error', '工具执行失败', error)
      
      // 抛出插件错误
      throw new PluginError(
        `工具执行失败: ${error.message}`,
        'TOOL_EXECUTION_FAILED',
        this.name,
        { originalError: error, params }
      )
    }
  }
}

最佳实践

1. 错误处理

typescript
// 总是捕获和处理错误
private async safeOperation(params: any): Promise<any> {
  try {
    const result = await this.riskyOperation(params)
    return { success: true, data: result }
  } catch (error) {
    this.log('error', `操作失败: ${error.message}`, { params })
    return {
      success: false,
      error: error.message,
      code: 'OPERATION_FAILED'
    }
  }
}

2. 参数验证

typescript
// 严格验证输入参数
private validateParams(params: any, schema: Record<string, ParameterDefinition>): void {
  for (const [key, definition] of Object.entries(schema)) {
    if (definition.required && !(key in params)) {
      throw new Error(`缺少必需参数: ${key}`)
    }
    
    if (key in params) {
      this.validateParameterValue(params[key], definition, key)
    }
  }
}

3. 资源管理

typescript
// 正确管理资源生命周期
protected async onDestroy(): Promise<void> {
  // 清理定时器
  if (this.timer) {
    clearInterval(this.timer)
    this.timer = null
  }
  
  // 关闭连接
  if (this.connection) {
    await this.connection.close()
    this.connection = null
  }
  
  // 清理事件监听器
  this.removeAllListeners()
}

4. 异步处理

typescript
// 正确处理异步操作
private async batchProcess(items: any[]): Promise<any[]> {
  const results = []
  const concurrency = 3 // 限制并发数
  
  for (let i = 0; i < items.length; i += concurrency) {
    const batch = items.slice(i, i + concurrency)
    const batchResults = await Promise.all(
      batch.map(item => this.processItem(item))
    )
    results.push(...batchResults)
  }
  
  return results
}

下一步

Released under the MIT License.