# @animated-waffle/client 中文文档

规范地址：https://npmcn.com/package/%40animated-waffle/client/

版本：0\.5\.10
npm 元数据更新时间：2026-11-05T03:14:27.877Z
中文译文更新时间：2026-11-06T17:28:34.997Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40animated-waffle/client
原文对照：https://npmcn.com/package/%40animated-waffle/client/?lang=original
项目主页：https://aniwaffle.com/docs/sdk
源码仓库：https://github.com/NaryaAI/animated-waffle

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：157 kB，9 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：2 个
- 首次发布：2026-08-06T13:40:26.764Z
- 最新版本发布：2026-11-05T03:14:27.683Z
- 近 30 天下载量：2583（2026-10-06 至 2026-11-04，npm 官方下载统计）
- 已发布版本数：33（近 12 个月 33 个）

## 中文简介

框架独立浏览器SDK 为纳里亚动画"华夫乐"谈话代理.

## 安装

```sh
npm install @animated-waffle/client
```

也可以使用：`pnpm add @animated-waffle/client`、`yarn add @animated-waffle/client`、`bun add @animated-waffle/client`

## README

# `@animated-waffle/client`

嵌入已出版的 Narya 对话的框架独立浏览器 SDK 代理:连接寿命周期、麦克风输入、文本输入、状态和 笔录. 反应应用程序应使用 [`@animated-waffle/react`](https://npmcn.com/package/%40animated-waffle/waffle-react),它会再出口整个API 并增加"神通"的渲染器。 对于普通 JavaScript 或其他浏览器框架,使用 [`@animated-waffle/web`](https://npmcn.com/package/%40animated-waffle/waffle-web) 财务报告和审定财务报表 `mountWaffleAvatar`此软件包是 无头; 它不会使字符.

安装当前 npm 发布而不复制可变注册版本 :

```bash
pnpm add @animated-waffle/client@latest
```

管理下的会期特性和 `sessionContext` 这里描述的API是 在0.3.1.版本中引入。 工作空间 [`package.json`](https://npmcn.com/package/%40animated-waffle/client/package.json) 实值 此寄存器版本的真相来源; `@latest` 决定 当前 npm 发布.

特工拥有它的外形,声音,和迅速。 媒体运行时间、API路线和 avatar 资产 URL 是 SDK 执行细节 。 生产是默认的 API来源;测试和非生产结合可能通过 `apiOrigin`。 。 。 .

## 连接

将永久的工作空间 API 密钥保留在您的服务器上 。 换一个 短寿命 Agent 会话符并给浏览器一个获取回调 每个连接一个:

```ts
import { WaffleClient } from '@animated-waffle/client'

const agentId = '22222222-2222-4222-8222-222222222222'
const endUserId = '55555555-5555-4555-8555-555555555555'
const waffle = new WaffleClient({
  agentId,
  // Set false for text-triggered, output-only applications.
  inputAudioEnabled: false,
  sessionContext: {
    userName: ' Space é ',
    timeZone: 'Asia/Shanghai',
  },
  sessionToken: async () => {
    const response = await fetch('/api/narya-session-token', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ agentId, endUserId }),
    })
    const body = await response.json()
    return body.token
  },
})

waffle.on('transcript', ({ id, role, text, final }) => {
  // Completed Narya conversation rows use the same id as persisted history.
  if (final) console.log(id, role, text)
})
waffle.on('transcriptProgress', ({ segmentId, role, text, complete }) => {
  // Ephemeral ASR/playout caption; never persist segmentId as a message id.
})

await waffle.connect()
```

`endUserId` 是每个终端用户一个稳定的裸UUID。 匿名申请可以 生成一次 `crypto.randomUUID()` 并坚持它在这个装置上.

## 地区

过 `region: 'jp'` 改为 `new WaffleClient({ agentId, sessionToken, region: 'jp' })` 或者说 `client.connect({ region: 'jp' })`SDK既选择日本API,又选择代理; `'us'` 选择美国。 连接选项可以覆盖构造器默认值 . 在切换活动会话前断开连接 。 被接纳的地区保持现有行为.

DEV, 添加 `apiOrigin: 'https://dev.aniwaffle.com'`;区域选择保留在DEV. 自定义 API 起源得到保存 。 自定义 `startSession` 接收回调 `region` 并且必须把它转发到他们的后端。 见 [区域指南](https://aniwaffle.com/docs/sdk#regions)。 。 。 .

## 创建者开发者反馈

开发者反馈是选入的, 除非应用程序供应 返回到它自己的创建者认证的后端。 SDK轻而易举地引用 当反馈被打开或保存时, API 返回了持续 源会话代码 :

```ts
const waffle = new WaffleClient({
  agentId,
  sessionToken: () => getSessionToken(agentId),
  developerFeedback: ({ agentId, sourceSessionId, signal }) =>
    fetch('/api/narya-developer-feedback-grant', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ agentId, sourceSessionId }),
      signal,
    }),
})
```

后端反应使用公共赠款形状 `{ endpoint, token, expires_at, source_session_id }`. 它必须作为 使用服务器侧工作空间密钥创建开发路径并薄荷赠款; 永远不要向浏览器暴露那把钥匙。 反馈端点只接收到 5分钟补助金 `credentials: 'omit'`。无法使用普通代理 届会符号 。 非启动 SDK 开发源头必须包含在 API 配置的源授权列表 .

`loadDeveloperFeedback()` 阅读当前私人草稿. `submitDeveloperFeedback()` 附加一个保存/更改 整个会话或持续的助理信息。 它从来不提交回合, 生成修订,或发布代理。 重新使用明确的反馈 `id` 在模糊的网络失败后重试.

以非生产环境为目标:

```ts
const waffle = new WaffleClient({
  agentId,
  sessionToken: () => getSessionToken(agentId),
  apiOrigin: 'https://animated-waffle-dev.narya.ai',
})
```

## API 表面

-   `sessionContext?: { userName?: string; timeZone?: string }` ——只提供 默认值 `sessionToken` 发起者. 非空白值的发送精确于 提供了;省略了空白值。 它相互排斥 高级 `startSession` 重新调用,所以象征性的消费者不会重现 原始的管理会话请求.
-   `reportedSource?: 'Web' | 'SDK' | 'Client' | 'Unknown'` ——自报 融合家庭只用于观察。 SDK 默认为 `SDK`。 。 。 .
-   `connect({ inputMode?, sessionId?, overrides? })` —— 说 `'push-to-talk'` (违约)或 `'automatic'`;只有在代理运行时间准备好时才能解决.
-   `session.agentStudioUrl?` ——服务器授权的仪表板目标精确 代理和源会话。 开发 UI 可显示“ 工作室的开放代理 ” 当它存在时; 不重建它从 `avatarId`. 旧协议-v2服务器 在滚动升级时可能会省略.
-   `inputAudioEnabled: false` 绝不要求或启用浏览器麦克风; 文本输入,代理音频,誊本,和再连接继续工作. 推开.. 关闭待谈控制失败 `input_audio_disabled`默认为 `true`,只有在特工准备好后才启用.
-   `muted` ——在特工不断表演时,沉默其声音:会话, 记录和神通的提示继续, 只有回放去安静.
-   `audioJitterBufferMs: 20` 首选的本地 WebRTC 音频缓冲器, 以毫秒计( 默认 20; 使用) `null` 用于浏览器默认值)。 浏览器仍然适应网络焦躁. 不支持的浏览器保持默认值.
-   `audioPlayback: false` ——客户端自己没有建立音频元素. 播放 `remoteAudioTrack` 自己; 引导语音的应用程序 自有元素、混音器或Web音频图必须关闭,或声音是 听到两次. `muted` 那没什么好做的.
-   `disconnect()`, (中文(简体) ), `sendText(text, { audioResponse? })`。 。 。 . `audioResponse` 默认 改为 `true`· ; `false` 保持输入的转折和记录,但抑制回复 声音为那个转弯.
-   `loadDeveloperFeedback()`, (中文(简体) ), `submitDeveloperFeedback(input)` ——只提供 上面有明确的创建者 BFF 回调.
-   `startPushToTalk()` 编号 : `commitPushToTalk()` 编号 : `cancelPushToTalk()`。 。 。 .
-   `on('connectionState' | 'session' | 'remoteAudioTrack' | 'transcriptProgress' | 'transcript' | 'agentSpeaking' | 'declined' | 'error', fn)` —— 说 `declined` 携带 故意保持沉默的操作者 调用返回 未订阅的函数.
-   完成连续行的谈话记录,随同要求 `id` 作为历史,目前一直 `final: true`提供方 句子/进度框架从未定义过公共对话行.
-   转写进度为平时并按键 `segmentId`; 用户 ASR 和助理播放器逐步更新,直到 `complete` 关闭它.
-   `connectionState`, (中文(简体) ), `session`, (中文(简体) ), `remoteAudioTrack` 获取器; `status` 这是 已贬值的0.1别名。 失败投出 `WaffleError` 与 `code` 键入 `stage`数字 : `session`, (中文(简体) ), `transport`, (中文(简体) ), `audio`, (中文(简体) ), `transcript`, (中文(简体) ), `avatar-load`,或 `avatar-renderer`失败 `connect()` 用同样的错误发出和拒绝 举个例子.

`./internal` 个人合同,是指 `@animated-waffle/react`这是 非公共API的一部分,可不经通知而更改.

见 [SDK 文档](https://aniwaffle.com/docs/sdk) 联 合 国 完整的整合指南.

## 申请会议

对于应用程序拥有的对话,使用 `application: true` 带有 `startSession` 调回已创建的媒体会话 `WaffleServer.startApplicationSession`后端保留单独的控制 grant;浏览器从不执行工具或转发特权回调 . 见 [应用会议合同](https://npmcn.com/package/docs/public/sdk.md#application-owned-tools-and-conversation-state)。 。 。 .

## 发展诊断

`client.diagnostics.server.waitDetails` 将输入交接到 LLM 启动(先发制人时为负),先给 TTS 请求(判决缓冲加连接), TTS 连接, 先给工人音频槽的 PCM , 以及 最初 PCM 的先行-静态估计. ASR自动定稿和回合终会决定分开 `server.asrFinalizationMs` 财务报告和审定财务报表 `server.endOfTurnDecisionMs` 字段。 老年工人忽略了这些领域.

对于RTC回放, `client.diagnostics.turn.transport` 包含在检测到回放后首250 ms的浏览器到LiveKit ICE RTT、 jitter-buffer/目标和设备播放平均值,以及 `sampleWindowMs`. 抽样同步完成并保留了原回放时间戳;音频从不等待诊断. 不支持、重置或 Stale 计数器 `null`。这些是重叠的诊断样本,而不是添加剂的单向网络延迟;服务器和客户端的观察可以描述不同的输入。 它们没有录音、记录、设备识别器或网络地址。 内置的Web/React 诊断面板使字段相同.

读取 `client.diagnostics` 并订阅 `client.on('diagnostics', render)`。 。 。 . 反应返回相同的快照 `waffle.diagnostics`反应 `useWaffle` 财务报告和审定财务报表 网络 `mountWaffleAvatar` 适配器显示一个崩溃的浮动诊断面板在 发展建设;生产违约。 他们 `diagnostics` 选项覆盖 可见度。 对内向视图, 使用 `WaffleDiagnosticsPanel` 或者说 `mountWaffleDiagnostics(host, client)` 并禁用自动覆盖. 无头客户端从未添加UI. 挂载面板从不启动连接或麦克风.

面板显示连接/ 媒体/ Avatar 状态, 连接阶段, 最新的客户端 输入端回放估计,安全出错和当前会话工作室链接. 更新的工人还报告使用ASR、LLM、TTS和工人-产出计时 工作室的减员。 客户端和服务器行有单独的关联ID和时钟; 不对阶段进行总和,也不将工人输出作为浏览器回放。 缺少数据 仍然无法使用。 语音输入活动和RTC/paired输出时间是估计数, 没有校正声学测量。 抓图不包括文本、音频、符号和原始 错误消息 。 面板是可选的;现有的计时遥测独立于面板.

## 麦克风抓取

`audioCapture` 接受本地 LiveKit 捕获限制(不包括自定义处理器). 它们应用在第一个麦克风打开之前,以及重新连接之后. 他们留在当地 ;认证、计费和服务器语音路由不变.

```ts
const client = new WaffleClient({
  agentId,
  sessionToken: () => fetchSessionToken(),
  // Only for an isolated virtual input or audio that already has echo processing.
  audioCapture: { echoCancellation: false },
})
```

保持正常扬声器/麦克风设置的回声取消功能。 拆开它 可以把特工的声音反馈回识别 并触发不必要的干扰. 不应用设备名检测或自动处理更改. 检查 `client.microphoneTrack?.getSettings()` 连接后检查 浏览器已实际启用; 更改已打开的音轨可能会被拒绝 . `useWaffle` 接受同样的选项。 同等内在限制保留 连接; 更改它们的值会重新创建客户端. 抓取选项不 更改 LiveKit 的服务器侧中断热身或回合结束设置 .

## 麦克风控件和会话事件日志

`client.microphone` 包含当前输入标签, 本地设备ID, 可用 输入、哑/启用的旗帜和切换状态。 标签可能空到 浏览器授予抓取权限 . `refreshInputDevices()` 仅列举; 它从不请求许可. `setInputDevice(deviceId)` 切换连接 调用,取消一个活动的 PTT 控件并重新组合抓取和级别观测。 A 类 失败的切换拒绝而不结束调用 。 选中的设备被重用 当客户端重新连接时。 浏览器上的设备列表更新 `devicechange`。 。 。 .

```ts
client.on('microphone', renderInputSelector)
client.on('inputLevel', renderMeter) // { rms, peak } in [0, 1], at most 20 Hz; null = unavailable
client.on('inputIssue', renderInputNotice) // null clears the current notice
await client.setInputDevice(selectedDeviceId)
```

测量仪测量能量,不识别的语音. 也用于应用程序 自己重播的( r)`audioPlayback: false`) (中文(简体) ). 它没有打开第二个麦克风.

`client.on('diagnosticEvent', handler)` 接受结构化会话活动; `client.diagnosticHistory` 保留本地调试的最新128, 包括 连接尝试失败 。 兼容工人自动存储这些事件 在经过认证的会话下。 不需要操作员专用仪器. 事件包括连接/再连接、明确断开、麦克风/轨道 状态和实际设备标签、设备更改、PTT按下/放行/取消、控制 承认/失败、PCM完成/字节、5秒能量摘要、, 记录长度,远程音频,回放哑音,中断和输入问题. 设备ID留在本地; 不包括音频、 文本内容、 证书和 URL 在客户报告中。 服务器工作流程日志单独保留有界限的模型输出.

交付是最好的努力:最多64起未发送事件,每批8起,稳定身份证明 重试分解和每次连接最多4 096个事件。 连续三次 发送失败停止重试此连接 。 失去连接或会话 永远无法接触到相容工人的,只能在当地历史上离开活动; 订阅 `diagnosticEvent` 通过您的应用程序的日志发送这些 . 客户端通过时间从服务器事件时间戳使用单独的时钟 .

## 常见问题

### @animated-waffle/client 是什么？

框架独立浏览器SDK 为纳里亚动画"华夫乐"谈话代理\.

### 如何安装 @animated-waffle/client？

在项目目录运行 npm install @animated-waffle/client，或使用 pnpm add / yarn add / bun add。

### @animated-waffle/client 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @animated-waffle/client 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @animated-waffle/client 可以商用吗？

@animated-waffle/client 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @animated-waffle/client 的下载量有多少？

根据 npm 官方下载统计，@animated-waffle/client 在 2026/10/06 – 2026/11/04 这 30 天内被下载 2,583 次，日均约 86 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @animated-waffle/client 还在维护吗？

最新版本 0\.5\.10 发布于 2026/11/05（2 天前）；至今共发布 33 个版本，其中过去 12 个月发布了 33 个；首次发布于 2026/08/06。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

