@vivix-ai/ivi-sdk-ts
v0.3.11
Published
TypeScript SDK for IVI events and WebSocket client.
Readme
IVI TS SDK
IVI 的 TypeScript SDK,当前包含:
- 全量实时事件定义、类型、校验与解析器
client模块下的IviClient实时客户端- 可插拔的
IviRealtimeTransport传输接口 - 迁移期兼容的 WebSocket transport
- 基于 OpenTelemetry API 的实时链路埋点
安装依赖
npm install开发命令
npm run generate:events -- --help
npm run generate:events -- ../ivicontrollane/api/realtime.yaml
npm run typecheck
npm test
npm run build开发提示
实时事件代码由 scripts/generate-events.mjs 从 AsyncAPI 文档生成:
npm run generate:events -- ../ivicontrollane/api/realtime.yaml无参数运行 npm run generate:events 会打印完整 help;真正生成时需要显式传入 realtime.yaml 路径。--out-dir 默认写入 src/events,也可以在 help 中查看并覆盖。修改该文档后,需要重新生成 src/events 下的类型、事件类、验证器、解析器和 parser 测试。
发布说明
dist 目录会随仓库一并提交到 GitLab,这样使用方可以直接通过 GitLab 仓库地址引入依赖,而不必额外执行本地构建。
SDK 也会发布到 npm 公共仓库 @vivix-ai scope 下:
npm publish发布前请确认已完成事件代码生成、类型检查、测试和构建,并确认当前版本号正确。
提交流程要求
只要修改了 src 下的源码或其他会影响产物的构建配置,推送到 GitLab 之前都必须先执行一次:
npm run generate:events -- ../ivicontrollane/api/realtime.yaml
npm run typecheck
npm test
npm run build确认 dist 已同步更新后才可以推送。
使用示例
WebSocket 兼容用法
import { IviClient } from "@vivix-ai/ivi-sdk-ts";
import { WebSocketTransport } from "@vivix-ai/ivi-sdk-ts/transports/websocket";
const transport = new WebSocketTransport({
url: "wss://example.com/realtime",
sessionId: "session-id"
});
const client = new IviClient({
transport
});
await client.connect();
client.onEvent((event) => {
console.log(event.type);
});OpenTelemetry 链路埋点
IviClient 只依赖 @opentelemetry/api,不会内置 exporter/provider,也不会直接请求任何观测后端。使用方或上层 SDK 负责配置 OpenTelemetry provider/exporter;未配置 provider 时,埋点会保持 no-op。
import { context, trace } from "@opentelemetry/api";
import { IviClient } from "@vivix-ai/ivi-sdk-ts";
const tracer = trace.getTracer("ivi-frontend-sdk");
await tracer.startActiveSpan("app.live.start", async (span) => {
const client = new IviClient({
transport,
telemetry: {
tracer,
context: context.active(),
attributes: {
"session.id": "session-id",
"vivix.surface": "api-platform"
}
}
});
try {
await client.connect();
} finally {
span.end();
}
});在传入 telemetry.context,或在 active span 内调用 connect() 时,IviClient 会把本次连接里的 connect、WebSocket 生命周期、错误和重连关键点挂到同一条外部链路下。正常的 WebSocket 消息收发不会逐条创建 span,而是聚合到 sdk.client.websocket 的计数属性里,例如 ivi.client.sent_events、ivi.client.received_events、network.sent_bytes 和 network.received_bytes,避免事件流量大时产生过多 trace 噪声。telemetry.attributes 会追加到 SDK span 上,请只放 session id、surface、版本号这类低基数字段,不要放 token、密钥、完整 payload 或用户文本。
自定义 transport
IviClient 不感知 LiveKit、WebRTC 或其他具体传输实现。它只依赖一个能连接、关闭、发送字符串、接收字符串的 transport。
import { IviClient, type IviRealtimeTransport } from "@vivix-ai/ivi-sdk-ts";
const transport: IviRealtimeTransport = {
connect: async () => {
// 加入 LiveKit room、打开 DataChannel,或连接任意跨端消息通道
},
close: () => {
// 关闭底层连接
},
send: (data) => {
// 发送 IVI JSON 事件字符串
},
onOpen: (listener) => {
// 底层连接打开后调用 listener()
return () => {};
},
onMessage: (listener) => {
// 收到底层消息后调用 listener(rawString)
return () => {};
},
onClose: (listener) => {
// 底层连接关闭后调用 listener(error?)
return () => {};
},
onError: (listener) => {
// 底层连接错误后调用 listener(error)
return () => {};
}
};
const client = new IviClient({ transport });
await client.connect();LiveKit adapter 边界
LiveKit 是推荐的 WebRTC 中转方案。浏览器默认实现通过独立子路径提供,根入口不会 re-export 该实现:
import { IviClient } from "@vivix-ai/ivi-sdk-ts";
import { LiveKitBrowserTransport } from "@vivix-ai/ivi-sdk-ts/transports/livekit-browser";
const transport = new LiveKitBrowserTransport({
url: "wss://livekit.example.com",
token: "livekit-token",
topic: "ivi-events"
});
const client = new IviClient({ transport });
await client.connect();
await transport.publishMicrophone({
echoCancellation: true,
noiseSuppression: true
});只有显式导入 @vivix-ai/ivi-sdk-ts/transports/livekit-browser 的浏览器应用需要安装 livekit-client。Node.js、React Native、Unity、小程序等运行时仍应使用各自可用的 LiveKit SDK,实现 IviRealtimeTransport 后注入 IviClient。
根入口不能 re-export 具体 LiveKit adapter,避免其他运行时被动加载浏览器实现。
