npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@koi-video/voice-realtime-sdk-beta

v0.1.3

Published

Voice realtime ChatClient: REST (realtime/voice) + Web RTC

Readme

@koi-video/voice-realtime-sdk-beta

浏览器端实时语音 SDK:HTTP 语音会话/start/stop),使用 Robot-Key / Robot-Token 鉴权;并集成 RTC(麦克风推流、远端音频、流消息用于字幕与控制)。Web RTC 客户端库作为普通依赖随本包安装,无需单独安装。

English documentation


概述

| 层级 | 职责 | | -------------- | ------------------------------------------------------------------------------------------ | | REST | 创建/结束语音会话;返回 room_namertc_infoapp_idtokenuser_id)。 | | RTC | 进房、发布麦克风、订阅远端音频、接收 stream message(字幕、打断等)。 | | ChatClient | 统一入口:startVoiceChaton 订阅事件;stopVoiceChatinterruptsetAudioEnabled。 |

  • 会话标识startVoiceChat 返回的 **sessionId** 与后端 **room_name** 相同,用于 stopVoiceChatinterruptsetAudioEnabled
  • 运行环境:麦克风与 RTC 需要安全上下文(HTTPS 或 localhost)。

安装

pnpm add @koi-video/voice-realtime-sdk-beta

RTC Web SDK 为本包的直接依赖,安装本包时由包管理器一并安装(本地路径、npm 或私有源均可)。


模块导出

import {
  ChatClient,
  VoiceEvents,
  DEFAULT_VOICE_API_BASE,
  RELATIVE_VOICE_API_BASE,
  generateDefaultUserName
} from '@koi-video/voice-realtime-sdk-beta';

| 导出 | 说明 | | ------------------------- | ------------------------------------------ | | ChatClient | 主客户端类。 | | VoiceEvents | 事件名字符串常量(见 事件)。 | | DEFAULT_VOICE_API_BASE | 默认 REST 根地址(直连网关)。 | | RELATIVE_VOICE_API_BASE | 开发代理用的同源路径,如 /openapi/v1/realtime/voice。 | | generateDefaultUserName | 未传 userName 时生成 user_${时间戳}_${随机串}。 |


REST 接口(SDK 内部调用)

使用 **fetch**、JSON 请求体,请求头:

  • Robot-KeyRobot-Token(由业务后台或控制台下发)
  • Content-Type: application/json

| 方法 | 路径(相对 apiBase) | 说明 | | ------ | ----------------- | ----------------------------- | | POST | {apiBase}/start | 发起会话;body 字段为下述 snake_case。 | | POST | {apiBase}/stop | 结束会话;user_nameroom_name。 |

apiBase 会做规范化(去掉末尾多余 /)。默认值为 DEFAULT_VOICE_API_BASE
apiBase 已包含语音模块路径,不要再/start/stop 前多拼一层 /voice,避免出现 .../voice/voice/start 这类重复路径。

成功启动时,响应通常包含 data.room_namedata.user_namedata.rtc_info(含 vendoruser_idparams.app_idparams.token)。


ChatClient

构造函数

new ChatClient(auth, options?)

**auth**(任选一种写法):

  • robot-key / robot-token,或
  • robotKey / robotToken

**options**

| 字段 | 类型 | 说明 | | --------- | -------- | ---------------------------------------------------------------------------------- | | apiBase | string | 可选。默认 DEFAULT_VOICE_API_BASE。前端经反向代理访问同一网关时,可设为 RELATIVE_VOICE_API_BASE 等同源路径。 |

方法

| 方法 | 说明 | | -------------------------------------- | --------------------------------------------------------------------------- | | on(eventName, handler) | 订阅事件。 | | off(eventName, handler) | 取消订阅。 | | startVoiceChat(options?) | 请求 POST .../start,发麦克。返回 **sessionId**(即 room_name)。 | | stopVoiceChat({ sessionId }) | 离房并请求 POST .../stop。会触发 SESSION_ENDED。若 RTC 已释放但 stop 接口失败,仍可能 throw。 | | interrupt({ sessionId }) | 通过流消息发送打断指令。 | | setAudioEnabled({ sessionId, bool }) | 通过音量控制本地采集开关(bool === false 为静音)。 |

startVoiceChat(options?)

| 字段 | 类型 | 说明 | | ------------------ | -------- | ------------------------------------ | | userName | string | 可选;不传则用 generateDefaultUserName()。 | | welcome | string | 可选欢迎语。 | | maxDuration | number | 最大通话时长(秒),对应 max_duration。 | | clientType | string | 默认 "websdk"。 | | expectedEngineId | string | 对应 expected_engine_id(Agent 等)。 | | segmentCode | string | 对应 segment_code。 |


事件

使用 client.on(VoiceEvents.XXX, handler)client.on('ALL', ...) 订阅。

VoiceEvents 常量

| 常量 | 值 | 触发时机 | | ----------------- | ----------------- | --------------------------------------------------------------------------------- | | SESSION_CREATED | SESSION_CREATED | HTTP 启动成功且就绪;载荷:{ sessionId }。 | | SESSION_ENDED | SESSION_ENDED | 用户 stopVoiceChat、RTC 异常断开、或结束流程中已发出 SESSION_ENDED;载荷:{ sessionId, reason }。 | | USER_MESSAGE | USER_MESSAGE | 流消息 topic === 'chat',用户侧;载荷:{ sessionId, content, segmentId?, timestamp? }。 | | ROBOT_MESSAGE | ROBOT_MESSAGE | 流消息 topic === 'chat',助手(role === 'llm');载荷同上。 | | INTERRUPT | INTERRUPT | 流消息 topic === 'interrupt';载荷:{ sessionId }。 | | ERROR | ERROR | 接口/RTC/解析等错误;载荷含 codemessagesessionId? 等。 | | ALL | ALL | 所有事件:**handler(eventName, data)**。 |

协议中暂未与流绑定的预留名:AUDIO_STARTAUDIO_END — 为与产品文档对齐写在 VoiceEvents 中,请勿依赖其实际触发

ALL 与扩展 topic

订阅 ALL 时,还可能收到:

| 第一个参数 eventName | 含义 | | ----------------- | ---------------------------------------------------- | | FLOW_DEBUG | topic === 'flow_debug' — 载荷含 sessionIdtext。 | | SIDE_INFO | topic === 'side_info' — 载荷含 sessionIdpayload。 | | STREAM_MESSAGE | 其余未单独映射的流 JSON。 |

常见 ERROR.code

| Code | 含义 | | -------------- | ----------------------- | | HTTP_* | 启动接口非 2xx。 | | NETWORK | 启动阶段 fetch 失败。 | | RTC_ERROR | 进房/推流失败。 | | STREAM_PARSE | 流消息解析失败。 | | CHAT_ERROR | 聊天消息带 errMsg。 | | RTC_STOP | 停止轨道/客户端异常。 | | STOP_API | 结束会话 HTTP 失败(本地可能已拆会话)。 |


代码示例

最小流程

import { ChatClient, VoiceEvents } from '@koi-video/voice-realtime-sdk-beta';

// 鉴权:Robot-Key / Robot-Token(示例从环境变量读取,实际可按业务注入)
const client = new ChatClient({
  robotKey: process.env.ROBOT_KEY,
  robotToken: process.env.ROBOT_TOKEN
});

// 错误:HTTP / RTC / 流解析等
client.on(VoiceEvents.ERROR, err => {
  console.error(err.code, err.message);
});

// 助手字幕;segmentId 用于多条流式片段合并为同一气泡
client.on(VoiceEvents.ROBOT_MESSAGE, ({ sessionId, content, segmentId }) => {
  console.log('bot:', content, segmentId);
});

// 用户侧语音识别文本
client.on(VoiceEvents.USER_MESSAGE, ({ content, segmentId }) => {
  console.log('user:', content, segmentId);
});

// 发起会话并进房、推麦;返回值 sessionId 与后端 room_name 相同
const sessionId = await client.startVoiceChat({
  expectedEngineId: 'your-agent-id'
});

// 发送打断 → 静音 → 开麦 → 离房并调用结束会话接口
client.interrupt({ sessionId });
await client.setAudioEnabled({ sessionId, bool: false });
await client.setAudioEnabled({ sessionId, bool: true });
await client.stopVoiceChat({ sessionId });

全局监听

client.on(VoiceEvents.ALL, (eventName, data) => {
  console.log(eventName, data);
});

开发环境代理(Vite 等)

apiBase 指到经代理的同源路径,避免浏览器跨域直连网关:

import {
  ChatClient,
  RELATIVE_VOICE_API_BASE
} from '@koi-video/voice-realtime-sdk-beta';

const client = new ChatClient(
  { robotKey: '...', robotToken: '...' },
  import.meta.env.DEV ? { apiBase: RELATIVE_VOICE_API_BASE } : {}
);

在开发服务器中将 /openapi(或你们使用的前缀)代理到真实网关。


本仓库 Demo

cd packages/voice-realtime-sdk
pnpm install
pnpm demo
pnpm demo:build    # 静态资源输出到 demo/dist(SDK 已打包)
pnpm demo:preview  # 本地预览 demo/dist(与开发环境相同的 /openapi 代理)

完整示例见 demo/(HTML + Vite;可选 HTTPS,见 demo/vite.config.js 中的 @vitejs/plugin-basic-ssl)。


许可证

UNLICENSED(内部使用 / 由团队发布策略决定)。