插件系统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
}