@kg-ui/client-sdk
v1.0.0
Published
智星客户端 SDK - 工具执行和 Widget 管理
Readme
@zhixing/client-sdk
智星客户端 SDK - LLM App 的客户端运行时治理层
概述
@zhixing/client-sdk 是一个专注于"LLM App 的客户端运行时治理层"的 TypeScript SDK。它负责 Tool → structuredContent → Widget 的调度与治理,不管理对话上下文,不包含 DOM 操作,只通过注入的 ToolExecutor 执行工具。
核心设计理念
- 单一职责: 专注于工具调度和 Widget 治理,不涉及对话管理
- 依赖注入: 通过注入的 ToolExecutor 执行具体工具,保持解耦
- 事件驱动: 使用事件机制实现组件间松耦合通信
- 类型安全: 提供完整的 TypeScript 类型定义和泛型支持
- 稳定接口: 所有对外 API 保持向后兼容
特性
- 🔧 工具调度: 通过注入的 ToolExecutor 执行工具,支持异步执行和错误处理
- 📊 结构化内容: 标准化的工具执行结果格式,支持文本和 Widget 混合内容
- 🎨 Widget 管理: Widget 状态管理和生命周期事件,与外部 Widget Runtime 集成
- 📡 事件驱动: 完整的事件系统支持,包括工具执行和 Widget 生命周期事件
- 🛡️ 类型安全: 完整的 TypeScript 类型定义,支持泛型和严格类型检查
- ⚡ 轻量级: 专注核心功能,保持简洁,无外部运行时依赖
- 🔍 工具发现: 内置工具注册表,支持工具描述和参数模式查询
- ⚠️ 错误处理: 统一的错误处理模型,提供详细的错误上下文和调试信息
安装
pnpm add @zhixing/client-sdk快速开始
基础用法
import { createSDK, type ToolExecutor } from '@zhixing/client-sdk';
// 实现工具执行器
const toolExecutor: ToolExecutor = {
async execute(name: string, params: any) {
// 实现具体的工具执行逻辑
switch (name) {
case 'calculator':
return { result: params.a + params.b };
case 'weather':
return {
result: { temperature: 25, condition: 'sunny' },
// 返回结构化内容
structuredContent: {
type: 'mixed',
content: [
{
type: 'text',
data: { text: `当前温度: ${25}°C`, format: 'plain' }
},
{
type: 'widget',
data: {
widgetId: 'weather-widget-1',
widgetType: 'weather-display',
props: { temperature: 25, condition: 'sunny' }
}
}
]
}
};
default:
throw new Error(`Unknown tool: ${name}`);
}
}
};
// 创建 SDK 实例
const sdk = createSDK({
toolExecutor,
debug: true
});
// 执行工具
const result = await sdk.executeTool('calculator', { a: 10, b: 20 });
console.log(result); // { success: true, data: { result: 30 } }完整配置示例
import { createSDK, type WidgetRuntime } from '@zhixing/client-sdk';
// 可选:实现 Widget Runtime
const widgetRuntime: WidgetRuntime = {
async mount(widget) {
console.log('Mounting widget:', widget.id);
// 实现 Widget 挂载逻辑
},
async unmount(widgetId) {
console.log('Unmounting widget:', widgetId);
// 实现 Widget 卸载逻辑
},
async update(widgetId, state) {
console.log('Updating widget:', widgetId, state);
// 实现 Widget 状态更新逻辑
}
};
// 创建 SDK 实例
const sdk = createSDK({
toolExecutor,
widgetRuntime, // 可选
debug: true // 可选,启用调试模式
});API 参考
createSDK(options)
创建 SDK 实例的主要入口函数。
配置选项 (SDKOptions)
interface SDKOptions {
toolExecutor: ToolExecutor; // 必需:工具执行器
widgetRuntime?: WidgetRuntime; // 可选:Widget 运行时
debug?: boolean; // 可选:调试模式,默认 false
}返回的 SDK 接口
interface SDK {
// 执行工具
executeTool<T = any>(name: string, params: any): Promise<ToolResult<T>>;
// 获取工具描述符列表
getToolDescriptors(): ToolDescriptor[];
// 获取 Widget 状态
getWidgetState(): Readonly<WidgetState>;
// 事件订阅
on(event: string, handler: EventHandler): () => void;
off(event: string, handler: EventHandler): void;
}事件系统
SDK 提供完整的事件系统,支持以下事件:
// SDK 就绪事件
sdk.on('sdk:ready', () => {
console.log('SDK 已初始化完成');
});
// 工具执行开始事件
sdk.on('tool:invoke', (data) => {
console.log('工具执行开始:', data.name, data.params);
});
// 工具执行完成事件
sdk.on('tool:result', (data) => {
console.log('工具执行完成:', data.name, data.result);
if (data.error) {
console.error('工具执行错误:', data.error);
}
});
// Widget 挂载事件
sdk.on('widget:mount', (data) => {
console.log('Widget 挂载:', data.widgetId, data.config);
});工具执行结果
工具执行返回标准化的结果格式:
interface ToolResult<T = any> {
success: boolean; // 执行是否成功
data?: T; // 工具返回的数据
error?: SDKError; // 错误信息(如果失败)
structuredContent?: StructuredContent; // 结构化内容(用于 Widget)
}结构化内容
支持文本和 Widget 混合的结构化内容:
interface StructuredContent {
type: 'text' | 'widget' | 'mixed';
content: ContentItem[];
}
interface ContentItem {
type: 'text' | 'widget';
data: TextContent | WidgetContent;
}
// 文本内容
interface TextContent {
text: string;
format?: 'plain' | 'markdown' | 'html';
}
// Widget 内容
interface WidgetContent {
widgetId: string;
widgetType: string;
props: Record<string, any>;
state?: Record<string, any>;
}错误处理
SDK 提供统一的错误处理模型:
import { SDKError, ConfigurationError, ToolExecutionError } from '@zhixing/client-sdk';
try {
const result = await sdk.executeTool('invalid-tool', {});
} catch (error) {
if (error instanceof SDKError) {
console.error('SDK 错误:', error.code, error.message);
console.error('错误上下文:', error.context);
if (error.cause) {
console.error('原始错误:', error.cause);
}
}
}高级用法
工具注册和发现
// 获取所有工具描述符
const descriptors = sdk.getToolDescriptors();
console.log('可用工具:', descriptors.map(d => d.name));
// 查看工具详细信息
descriptors.forEach(descriptor => {
console.log(`工具: ${descriptor.name}`);
console.log(`描述: ${descriptor.description}`);
console.log(`参数:`, descriptor.parameters);
console.log(`返回值:`, descriptor.returns);
});Widget 状态管理
// 获取当前 Widget 状态
const widgetState = sdk.getWidgetState();
console.log('活跃的 Widget:', Array.from(widgetState.activeWidgets));
// 监听 Widget 状态变化
sdk.on('widget:mount', (data) => {
const updatedState = sdk.getWidgetState();
console.log('Widget 状态已更新:', updatedState);
});调试模式
启用调试模式可以获得更详细的错误信息和日志:
const sdk = createSDK({
toolExecutor,
debug: true // 启用调试模式
});
// 调试模式下,错误会包含更多详细信息
try {
await sdk.executeTool('test', {});
} catch (error) {
// 错误对象会包含详细的调试信息
console.error('详细错误信息:', error);
}项目结构
src/
├── core/ # 核心功能
│ ├── sdk.ts # SDK 主入口和核心实现
│ ├── eventBus.ts # 事件总线系统
│ └── toolRuntime.ts # 工具运行时调度
├── types/ # TypeScript 类型定义
│ ├── tool.ts # 工具相关类型
│ ├── result.ts # 结果相关类型
│ ├── widget.ts # Widget 相关类型
│ ├── meta.ts # 元数据和配置类型
│ └── index.ts # 类型统一导出
├── registry/ # 工具注册表
│ └── appRegistry.ts # 工具描述发现和管理
├── widget/ # Widget 适配器
│ └── widgetAdapter.ts # Widget Runtime 适配层
├── errors/ # 错误处理
│ └── SDKError.ts # 统一错误模型
├── test/ # 测试文件
│ ├── *.test.ts # 单元测试
│ └── fast-check.test.ts # 属性测试
├── version.ts # 版本信息
└── index.ts # 主入口文件开发
# 安装依赖
pnpm install
# 开发模式(监听文件变化)
pnpm dev
# 构建生产版本
pnpm build
# 运行测试
pnpm test
# 类型检查和代码规范
pnpm lint
# 清理构建文件
pnpm clean测试策略
项目采用双重测试方法,确保代码质量和正确性:
测试框架
- Vitest: 现代化的测试运行器,快速且功能丰富
- fast-check: 属性测试库,支持生成随机测试数据进行全面测试
- Windows 兼容: 针对 Windows 环境进行了优化配置
测试类型
单元测试: 验证具体示例和边界情况,测试组件间的集成点
属性测试: 验证通用属性在所有输入下都成立,每个属性测试运行至少 100 次迭代
# 运行所有测试
pnpm test
# 运行测试并显示覆盖率
pnpm test --coverage
# 监听模式运行测试
pnpm test --watch版本信息
当前版本: 1.0.0
许可证
MIT License - 详见 LICENSE 文件
