Compare commits

..
Author SHA1 Message Date
xiaomoandmultica-agent 958c6962fb HEL-908 R1/R2 rework (HEL-909 review): whole-turn reasoning gate + cg.interrupt data channel
R1 — reasoning separation truly closed. The streaming hold leaked wholesale
on real token arrival (review A1: 'private reasoning '*20 beyond the 128-char
bound, no sentence ender; review A2: a Chinese sentence ender released the
hold) AND the adapter consumed the stray closer, so the app-level turn split
could never recover — the previous 'persistence and receipt always clean'
claim was false and is retracted. Per the engineering ruling the adapter now
has two explicit endpoint modes (GOV-006, no heuristics, no new engine):
buffer_turn (TurnReasoningGate) emits NOTHING during generation, splits the
whole turn at stream end and only then delivers the clean visible text; it
is set explicitly for all tiers in config/models.yaml (first visible text
waits for the full generation; cancelled/timed-out turns emit nothing and
end exactly as before — recorded and test-pinned, low latency NOT claimed).
stream (default, backward compatible) keeps explicit-tag/field semantics and
passes stray closers through unmodified so the turn-level split keeps its
signal. Both review strings and the recorded id=12 stream replay clean at
every chunk size through the real adapter and the real app into chat.delta,
the archive and the receipt; normal zh/en preserved byte-for-byte; unclosed
explicit thinking still fails honestly.

R2 — an authoritative interrupt when the LLM already finalized and TTS is
still playing (review evidence C: zero interrupts, old audio played out).
The page's existing hush() entry (ChatPanel untouched) now also publishes
{"v":1} on the room's own reliable data channel topic cg.interrupt
(fire-and-forget: a dropped publish never blocks or breaks the text send);
the worker subscribes data_received, validates topic/sender/payload and
calls session.interrupt(force=True) — the SDK's own programmatic interrupt,
force confirmed against the installed 1.8.8 source (non-force raises
RuntimeError on allow_interruptions=False speech). Failures log loudly; the
listener is unloaded via add_shutdown_callback; the server-cancel path in
llm_chat_api also interrupts with force and logs failures.

Verification (offline, zero real requests): real-SDK harness 8/8 including a
real SpeechHandle with a genuinely pending playout wait released by the
cg.interrupt message after a clean chat.final (evidence-C shape) plus the
full validation matrix; .venv311 full suite 480 passed / 8 skipped (2
test_r3 failures pre-exist at 5625de6); web npm ci from the existing lock,
typecheck 0 errors, lint 0 errors + 1 pre-existing warning, vitest 148/148,
build ok; ruff clean; check_requirements vs origin/main and b8ec832 with the
corrected handoff.

Co-authored-by: multica-agent <github@multica.ai>
2026-10-28 22:21:16 +08:00
xiaomoandmultica-agent b8ec832f35 HEL-908: terminal chat.cancelled + no-revive gate for text interrupt; reasoning/content separation at the adapter seam
Bug 1 (recorded call1): server-side cancel ended the voice SSE without a
terminal frame BEFORE the first delta (worker.log:108 SDK retry 13ms after
the text POST); the adapter raised a connection error, livekit-agents 1.8.8
silently retried the same turn_id, the retry re-acquired the gate, cancelled
the user's text turn and re-spoke a full ~32s reply. The HEL-907 claim that
the _retry_on_chunk_sent guard never worked is corrected: the guard only
applies after output (output_sent), verified against the installed SDK
source. Fix: explicit chat.cancelled terminal frame; a cancelled turn_id is
refused re-activation (never touches the newer active turn); the worker ends
cancelled turns on the SDK's own 499 path (no retry) and stops the cached
playout via SpeechHandle.interrupt(); a server_cancelled latch short-circuits
any re-entry with zero network. Failed-turn retries, completed-turn replay
and receipt validation are unchanged (dedicated tests).

Bug 2 (recorded row id=12): the endpoint streams implicit-open reasoning
plus a stray </think> inline in content into subtitles and TTS. Fix:
ReasoningSeparator at the OpenAI-compat adapter seam (cross-chunk safe,
reasoning_content field side-channel on LLMDelta.reasoning, never persisted)
plus a turn-level split before persist/final/receipt. Recorded stream
replays clean at every chunk size; normal zh/en content preserved
byte-for-byte; documented residual: implicit-open reasoning whose closer
lies beyond the 128-char hold streams partially (persistence stays clean).

Offline verification: .venv311 full suite 445 passed / 5 skipped (2
pre-existing test_r3 failures fail identically at 5625de6); real-SDK harness
(livekit-agents 1.8.8, agent venv) 5/5; reasoning separation 37/37; ruff
clean. Zero real requests, zero deployment, no dependency changes.

Co-authored-by: multica-agent <github@multica.ai>
2026-10-28 21:27:08 +08:00
xiaomoandmultica-agent 5625de6606 HEL-907: custom-voice web flow + 3 real calls window record, budget accounts, recycle evidence; hel900 harness minimal fix
Co-authored-by: multica-agent <github@multica.ai>
2026-10-28 20:29:23 +08:00
145 changed files with 3760 additions and 19 deletions
+5
View File
@@ -23,6 +23,9 @@ tiers:
api_key_env: null
timeout: 60.0
temperature: 0.85
# HEL-908/909:该端点会把隐式开头思考(无 <think>、模板预填)混入 content,
# 只能整轮缓冲后分离;首段可见文本因此等整轮生成完成(见 reasoning.py)。
reasoning: buffer_turn
# ---- 中档:可以指向同一个模型,但配更短的上下文预算 ----
# 省钱的杠杆通常不是换更小的模型,而是少喂上下文。
@@ -33,6 +36,7 @@ tiers:
api_key_env: null
timeout: 40.0
temperature: 0.7
reasoning: buffer_turn
# ---- 本地小模型:后台任务的主力 ----
# 没有本地服务时,把它指向 openai_compat 的远端小模型即可。
@@ -43,6 +47,7 @@ tiers:
api_key_env: null
timeout: 20.0
temperature: 0.4
reasoning: buffer_turn
# ---- 场景 → 档位 ----
# 改这里就能调成本结构,不用改代码。
+52
View File
@@ -0,0 +1,52 @@
{
"baseline_version": "1.12",
"read_commit": "038f1eeae71a9f67362d4694548d7d8116e0e35f",
"task": "HEL-907:验证网页自定义声音和三通真实交谈。白栖知批准(主卡评论 01a18246-672a-7a19-9e8a-69c6f547a232 同意这轮测试)后,在统一源码 038f1ee 上执行既有锁定依赖构建与浏览器脚本独立复跑;隔离部署(8360/8361 双入口同进程、8363 WSS 桥、8082 专属 worker、共享 TTS 9880 与面板 8090 窗口内临时恢复);真实网页链路(参考录音上传→cg- 登记→真实 TTS 试听→应用);三通真实通话验证 worker 实用音色与会话 voice 字段一致、通话中改选不换声下一通生效;并入 HEL-879 遗留的文字打断在播语音与打断停声时延量测;全程按批准上限执行并在结束后回收 cg- 条目、恢复共享服务、封账交付。",
"requirement_ids": [
"CG-006",
"CG-009",
"CG-010",
"CG-013",
"CG-014",
"CG-015",
"CG-016",
"CG-018",
"CG-019",
"CG-020",
"CG-021",
"AM-001",
"GOV-001",
"GOV-002",
"GOV-003",
"GOV-004",
"GOV-005",
"GOV-006",
"DEL-001"
],
"deliverable": "docs/rework/hel907/(window-record.md 窗口记录、build/ 构建与浏览器独立复跑日志、web/ 真网页链路截图与试听音频、window/ 逐通字幕/帧时间轴/回流音频/账本/快照);web/tests/hel900_shots.mjs 一处最小脚本适配(HEL-903 后 503 登记进入先刷新状态,检查意图不变,产品代码零改动);服务器证据包 /opt/cybergril-hel907/hel907-evidence-20261028.tar.gz(sha256 37ee1881…2e07e)。实测结果:网页自定义声音全链真实完成(cg-f2ec321d 登记 1 次出站、真实试听 2 次含音频存证、应用后 call1/call2 会话 voice=cg-f2ec321d 且 tts.log 合成音色逐一对应);call2 通话中改选 rain 本通不换声(worker 状态文件钉住)、call3 voice=rain 下一通生效;文字打断在播语音发现真实缺陷(文字轮被 worker 静默重试链取消、语音播完约 32 秒、文字无回复,DB/字幕/api.log 三层证据,源码机制定位至 llm_chat_api.py 重试守卫失效,本卡按边界不修);回放打断 turn_cancel 真实发生但帧级停声时延未取得(打断源过轻+旧轮无可闻声,如实不冒充);全部上限内完成(LLM 8/20 请求、23958/60000 tokens、嵌入 0、建房 4/6、通话 3/3、试听 2/10、通话 TTS 11/40、连续 ASR 195.16/2400 秒、重连 0、新增付费 0,时窗 18 分 32 秒);cg- 条目经 8090 删除入口回收、共享注册表恢复 11 支内置原样、9880/8090 按窗口前状态停回、8360/8361/8363/8082 全停、LiveKit 房间清空。",
"acceptance": [
"构建独立复跑:npm ci(既有锁文件);typecheck 0 错、lint 0 错 1 既有警告、vitest 148/148、build 成功;hel900 浏览器 83/83(1 处最小脚本适配已声明)、hel903 浏览器 90/90(零改动);本机既有 Chromium 156 运行时库解压到用户目录加载,未下载浏览器、未装系统包",
"真网页链路(真实浏览器经 HTTPS 8361):female_soft.wav 上传前 sha256 只读核对一致;登记成功 cg-f2ec321d(8090 唯一写者,参考文字手填、转写 0);真实 TTS 试听 24kHz/3.72s 音频存证且页面真实播放;应用后 /api/voice/selection 一致;逐步截图与网络事件留证",
"通话验证:call1/call2 会话响应 voice=cg-f2ec321d 与 worker 实际合成音色(tts.log)一致;字幕 v2 seq 单调、turn_end/turn_cancel 生命周期正常;挂断 DELETE 200、房间真实删除、删后仅约 20ms 在途帧",
"通话窗口持有:call2 通话中改选 rain 返回 200 而本通 worker 状态文件保持 cg-f2ec321d;call3 会话 voice=rain 下一通生效;会话响应 voice 与 worker 实读一致",
"文字打断在播语音:缺陷如实记录并可复现核对(chat_message id=6 cancelled / id=5、id=8 sent;call1.subtitles.jsonl t0=1793189878442 前后;api.log 第 122-129 行五次 POST 时序),不冒充通过",
"打断停声:回放打断 turn_cancel 真实发生(FunASR 真实识别);帧级旧声停止时延明确未取得(打断源 RMS 过轻致 VAD 15 秒后才判、旧轮 LLM 卡死无可闻声),同钟帧时间轴方法已备(call1/call3.frames.json),不捏造数字",
"上限与封账:全部类别含失败口径计数并留实时账本快照;触线为零;封账后服务全停、cg- 回收前后快照比对、11 支内置与全局默认零变化、共享服务按前快照恢复(9880/8090 窗口前停机→停回)、保护端口零接触、新增付费 0"
],
"deferred": [
"文字打断在播语音缺陷修复与复测:worker 适配器 llm_chat_api.py 重试守卫(_retry_on_chunk_sent 从未置真)与文字/语音互打断语义修复,交总管安排专项卡;修好前不得声称文字可打断语音",
"帧级打断停声时延:方法已验证,待响亮短促打断源+她正在可闻说话时机复测;真实用户麦克风起声时延(D3 用户动作:局域网设备浏览器开 https://192.168.200.12:8361,证书两处高级→继续,允许麦克风后对她说话,建议每次 ≤2 分钟)与 iOS Safari/安卓 Chrome 真机路径未测,交总管向用户交付入口",
"CG-009/R6 自定义音色删除入口与完整备份恢复、R5 整体验收、R1–R7 完整功能继续按获批依赖承接;本卡通过不等于自定义音色用户验收或 R5 完成",
"本轮窗口已封账:LLM 8/20、tokens 23958/60000 等余额不自动授权新窗口;后续窗口须另行获批并显式布防"
],
"requirement_changes": [],
"verification": [
"构建/浏览器:docs/rework/hel907/build/*.log(typecheck/lint/vitest/build/hel900-browser/hel903-browser)与 hel900-shots/hel903-shots 截图",
"网页链路:docs/rework/hel907/web/*.png 逐步截图、preview-cg-f2ec321d.wav 真实合成试听音频、webflow-result.json 网络事件与最终 selection",
"三通通话:docs/rework/hel907/window/call{1,2,3}.json + subtitles.jsonl + frames.json + agent.wav(回流音频逐通落盘)",
"用量与闸门:window/asr-usage.jsonl 与 asr-usage-summary.json(hel907-20261028-a 逐通 95.18/41.34/58.64 秒,confirmed=conservative);budget 快照在 call*.json;tts 窗口段数以 tts-window-tail.log 核对",
"缺陷证据链:call1.subtitles.jsonl + api.log + chat_message 行(id5/6/8)+ 源码定位(src/cybergril/voice/llm_chat_api.py:87-90 与 api/app.py:577-605 取消路径)",
"回收与恢复:voices-before.json / voices-before-recycle.json / panel-list-after-recycle.json 前后比对;pre/post-window-state.txt 端口与 GPU 快照;post 状态 8360/8361/8363/8082/9880/8090 无监听、8300/8310/8320/8350 原样、8340 停机",
"需求检查:check_requirements.py 对 origin/main 与 038f1ee 各带 --handoff 本文件通过(日志随交付);未验证项(真实用户麦克风、真机 Safari/Chrome、帧级停声时延)已如实标注"
]
}
+48
View File
@@ -0,0 +1,48 @@
{
"baseline_version": "1.12",
"read_commit": "5625de6606a607a9d4fd583fe8a52d93d6d2b4ea",
"task": "HEL-908 两轮定点返修(第二轮为 HEL-909 审核不通过后的集中返修一次)。第一轮修复文字打断丢字/旧轮复活/旧语音32秒(chat.cancelled 终态帧+cancelled 轮拒绝重新激活+worker 499 不重试+SpeechHandle.interrupt 停播,HEL-909 复核通过)。第二轮按总管裁定修两个核心缺口:R1 思考分流改显式整轮缓冲模式(原流式 hold 在中文句号/超128字符形状下整段泄漏且 closer 被适配层提前删除、轮级 split 无法兜底,第一轮『落库与 receipt 始终干净』表述不实已删除);R2 补上 LLM 已 final、TTS 仍在播时的权威打断通道(网页既有 hush() 入口经房间数据通道发 cg.interrupt,worker 订阅校验后 session.interrupt(force=True))。全部离线、零真实请求、零部署、零新依赖。",
"requirement_ids": [
"CG-006",
"CG-010",
"CG-013",
"CG-014",
"CG-015",
"CG-016",
"CG-018",
"CG-019",
"CG-020",
"CG-021",
"AM-001",
"GOV-001",
"GOV-002",
"GOV-003",
"GOV-004",
"GOV-005",
"GOV-006",
"DEL-001"
],
"deliverable": "同分支追加提交(agent/2/15e79a2458bb,第一轮 b8ec832 之上)。R1:providers/llm/reasoning.py 重做为双显式模式——TurnReasoningGate(buffer_turn,整轮缓冲零中途外发,流结束 split_reasoning 后一次性下发干净正文;取消/超时行为不变)与无启发式 ReasoningSeparator(stream 默认:仅滤显式 <think> 块跨chunk安全,stray closer 原样透传保住轮级兜底信号);openai_compat 显式 reasoning 模式参数;LLMConfig.reasoning 字面量校验+models.yaml 三档显式 buffer_turn(未配置=既有语义,向后兼容)。R2:web/src/voice/session.ts+livekit.ts 纯传输接线(VoiceRoom.interrupt(),既有 hush() 附带 publishData reliable topic=cg.interrupt,fire-and-forget 不阻塞文字发送,零视觉改动);worker.py bind_interrupt_channel(本房间 data_received 订阅,topic/发送者/载荷三重校验,session.interrupt(force=True),失败大声留痕,add_shutdown_callback 卸载);llm_chat_api._interrupt_owner 改 force=True+留痕。文档:docs/rework/hel908/summary.md 重写(删除不实表述、保留原始证据与纠偏、记录等待代价与边界),tests-remote-r2.log、web-r2.log、check-requirements.log。",
"acceptance": [
"R1 评审复现串逐字/小块经真实 OpenAICompatLLM→真实 app→持久化/receipt:'private reasoning '*20+'</think>回答。' 与 '我先想一下。内部思考</think>回答。' 的 chat.delta、落库行、chat.final、receipt text_hash 全部只含干净正文(buffer_turn 生成中零外发,修复前同输入已被本卡离线复现整段泄漏);记录流 id=12 按 1~1000 任意分块同样全干净;正常中英文正文逐字节保留;未闭合显式思考→空正文→诚实 chat.error;stream 模式显式块/推理字段/跨 chunk 语义保持,stray closer 透传可被 app 轮级 split 清理",
"R1 等待代价如实记录并测试固定:buffer_turn 首个可见正文等整轮生成完成(生成中零 chat.delta);取消轮照常 chat.cancelled 零泄漏、超时照常 chat.error;无 closer 无字段的推理不可识别边界已声明,不虚称全好",
"R2 真实 SDK 证明 8/8(agent venv 1.8.8):真实 SpeechHandle(allow_interruptions=False 覆盖 force 语义)+真实 pending 播放等待(wait_if_not_interrupted)——完整轮 chat.final 干净结束后(评审 evidence C 形状)注入 cg.interrupt 数据消息,播放等待被真实 interrupt 释放、句柄 interrupted、force=True 断言成立;非 force 在该句柄上 RuntimeError 复核;校验矩阵(错 topic/服务端来源/自身/坏载荷/错版本)零触发;卸载后零触发;session 未运行大声失败不崩溃",
"R2 app 集成记录:完整语音轮后的文字轮为普通轮(无任何行被取消、无 phantom 行);web 侧 hush() 在 speaking/thinking 才发消息且本地静音反馈保持,下一回复恢复正常收听路径未动;ChatPanel/视觉零改动",
"回归:.venv311 全量 480 passed/8 skipped(2 个 test_r3 失败在基准 5625de6 同样失败,预先存在);第一轮 5 项 SDK 检查全保持(取消终态/不复活/不重试/真实连接错误仍有限重试/完成轮流式+receipt 不变);web npm ci(既有锁文件)typecheck 0 错、lint 0 错 1 既有警告、vitest 148/148、build 成功;ruff 全绿;models.yaml 新键经 ModelsConfig 实际解析"
],
"deferred": [
"真实端到端复测(真实房间/真人打断时延/真机/真实端点思考出现频率与长回复起播延迟)须按授权窗口安排;R2 离线证明是真实 SDK 句柄/等待语义+实装源码核对,不冒充端到端毫秒指标",
"无 closer、无 reasoning 字段、无开头标签的推理任何客户端模式都不可识别,彻底解决需上游自行分流(字段或服务端 parser),零真实请求边界内无法探测——最小缺口如实声明",
"chat.cancelled 的前端可见呈现与 ChatPanel 取消判定 limit 扩大(HEL-909 建议 #3/#4,非阻塞)未动:前者属界面核心交视觉总监,后者纯展示层既有行为",
"gen_hel877_sdk_check harness 在基准上即因 HEL-906 导入失效(前轮已留证),交总管决定维护安排;本卡 SDK 验证由 test_sdk_livekit_hel908.py 覆盖(8 项,agent venv 可独立复跑)",
"R1–R7 完整功能、真实用户麦克风、视频/口型、记忆长跑继续按获批依赖承接;本卡不构成整产品完成"
],
"requirement_changes": [],
"verification": [
"docs/rework/hel908/summary.md:两轮根因/纠偏/方案/等待代价/边界全记录;第一轮不实表述已删除,原始证据与纠偏保留",
"docs/rework/hel908/tests-remote-r2.log:.venv311 全量 480 passed/8 skipped/2 pre-existing + agent venv SDK harness 8/8 实况",
"docs/rework/hel908/web-r2.log:typecheck/lint/vitest 148/148/build",
"tests/test_sdk_livekit_hel908.py 可在任何装有 livekit-agents 1.8.8 的环境复跑(pytest 或 --standalone),命令写在文件头",
"需求检查:check_requirements.py 对 origin/main 与 b8ec832 各带 --handoff 本文件通过(日志 docs/rework/hel908/check-requirements.log)"
]
}
+13
View File
@@ -0,0 +1,13 @@
> cybergril-web@0.1.0 build
> tsc --noEmit && vite build
vite v6.3.6 building for production...
transforming...
✓ 59 modules transformed.
rendering chunks...
computing gzip size...
dist/index.html 0.49 kB │ gzip: 0.35 kB
dist/assets/index-B8TdHoQm.css 88.58 kB │ gzip: 18.37 kB
dist/assets/index-ba4PURHH.js 342.44 kB │ gzip: 114.48 kB
✓ built in 680ms
@@ -0,0 +1,85 @@
PASS mock is this hel900 mock
PASS moon-desktop: no microphone before anything is tapped
PASS moon-desktop: opening the section only reads the list
PASS moon-desktop: says when a change takes effect
PASS moon-desktop: recording state is explicit and the microphone is live
PASS moon-desktop: audio only, never the camera
PASS moon-desktop: stopping keeps the take and releases the microphone
PASS moon-desktop: the take is labelled as your reference, not her voice
PASS moon-desktop: register needs reference text or an explicit transcription opt-in
PASS moon-desktop: the upload is real PCM WAV (16 kHz mono 16-bit), raw body + query
PASS moon-desktop: the new voice is chosen for a preview; apply waits for it
PASS moon-desktop: a fresh preview plays and only then can be applied
PASS moon-desktop: the preview is labelled as her synthesized voice, not your reference
PASS moon-desktop: the preview actually plays in the page
PASS moon-desktop: applied — current voice shown, from the next call
PASS moon-desktop: no object URL or microphone left after closing settings
PASS fog-desktop: no microphone before anything is tapped
PASS fog-desktop: opening the section only reads the list
PASS fog-desktop: says when a change takes effect
PASS fog-desktop: recording state is explicit and the microphone is live
PASS fog-desktop: audio only, never the camera
PASS fog-desktop: stopping keeps the take and releases the microphone
PASS fog-desktop: the take is labelled as your reference, not her voice
PASS fog-desktop: register needs reference text or an explicit transcription opt-in
PASS fog-desktop: the upload is real PCM WAV (16 kHz mono 16-bit), raw body + query
PASS fog-desktop: the new voice is chosen for a preview; apply waits for it
PASS fog-desktop: a fresh preview plays and only then can be applied
PASS fog-desktop: the preview is labelled as her synthesized voice, not your reference
PASS fog-desktop: the preview actually plays in the page
PASS fog-desktop: applied — current voice shown, from the next call
PASS fog-desktop: no object URL or microphone left after closing settings
PASS moon-phone: no microphone before anything is tapped
PASS moon-phone: opening the section only reads the list
PASS moon-phone: says when a change takes effect
PASS moon-phone: recording state is explicit and the microphone is live
PASS moon-phone: audio only, never the camera
PASS moon-phone: stopping keeps the take and releases the microphone
PASS moon-phone: the take is labelled as your reference, not her voice
PASS moon-phone: register needs reference text or an explicit transcription opt-in
PASS moon-phone: the upload is real PCM WAV (16 kHz mono 16-bit), raw body + query
PASS moon-phone: the new voice is chosen for a preview; apply waits for it
PASS moon-phone: a fresh preview plays and only then can be applied
PASS moon-phone: the preview is labelled as her synthesized voice, not your reference
PASS moon-phone: the preview actually plays in the page
PASS moon-phone: applied — current voice shown, from the next call
PASS moon-phone: no object URL or microphone left after closing settings
PASS fog-phone: no microphone before anything is tapped
PASS fog-phone: opening the section only reads the list
PASS fog-phone: says when a change takes effect
PASS fog-phone: recording state is explicit and the microphone is live
PASS fog-phone: audio only, never the camera
PASS fog-phone: stopping keeps the take and releases the microphone
PASS fog-phone: the take is labelled as your reference, not her voice
PASS fog-phone: register needs reference text or an explicit transcription opt-in
PASS fog-phone: the upload is real PCM WAV (16 kHz mono 16-bit), raw body + query
PASS fog-phone: the new voice is chosen for a preview; apply waits for it
PASS fog-phone: a fresh preview plays and only then can be applied
PASS fog-phone: the preview is labelled as her synthesized voice, not your reference
PASS fog-phone: the preview actually plays in the page
PASS fog-phone: applied — current voice shown, from the next call
PASS fog-phone: no object URL or microphone left after closing settings
PASS file: a renamed non-WAV is refused in the browser, nothing uploaded
PASS file: a 22 kHz stereo WAV becomes 16 kHz mono
PASS asr: opting in enables register with empty text
PASS offline: says so, keeps the take, sends nothing
PASS 503: honest message, take still there for a retry
PASS double tap registers once; transcription only on explicit opt-in
PASS asr: the transcribed text is shown back
PASS late: an older preview arriving after switching is dropped
PASS bad preview: refused, nothing playable shown
PASS preview 503: honest message
PASS apply 409: message, selection unchanged
PASS cancel: microphone released, take discarded
PASS leaving the section mid-take releases the microphone
PASS coming back says the take was dropped
PASS denied: says why, nothing recording
PASS an unregistered take guards leaving
PASS after leaving, nothing of the section remains
PASS list unconfigured: honest card, no microphone, no 'adjustable' tag
PASS list no-route: honest card, no microphone, no 'adjustable' tag
PASS list panel-down: honest card, no microphone, no 'adjustable' tag
PASS panel back: retry shows the list
PASS no registration or apply was ever cut off by the page itself
83/83 passed
+1
View File
@@ -0,0 +1 @@
hel900 mock on 8900 pid 2311407
Binary file not shown.

After

Width:  |  Height:  |  Size: 849 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 827 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 831 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 802 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 814 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 797 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 814 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 861 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 856 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 856 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 836 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

@@ -0,0 +1,92 @@
PASS mock is this hel903 mock
PASS moon-desktop: services — TTS row says configured + health probe reachable
PASS moon-desktop: services — ASR row claims no probe it does not have
PASS moon-desktop: services — no voice row says "尚未接通" or "已接通"
PASS moon-desktop: services — reading status opens no microphone
PASS moon-desktop: a voice is applied through the existing flow
PASS moon-desktop: settings still says a change takes effect at the next call
PASS moon-desktop: call line shows 本次通话 voice from the session answer
PASS moon-desktop: subtitles still show beside it
PASS moon-desktop: a choice made during the call does not change this call
PASS moon-desktop: ending the call releases the microphone and drops the pin
PASS moon-desktop: the next call shows the new voice
PASS moon-desktop: 500 after filing — says it may be registered and to refresh first
PASS moon-desktop: offers 刷新列表 and words a second registration as a checked choice
PASS moon-desktop: the list is not re-read or re-registered behind your back
PASS moon-desktop: refreshing names the new numbered entry
PASS moon-desktop: the numbered entry is marked as missing local metadata
PASS moon-desktop: after it is found the cautious button goes away
PASS fog-desktop: services — TTS row says configured + health probe reachable
PASS fog-desktop: services — ASR row claims no probe it does not have
PASS fog-desktop: services — no voice row says "尚未接通" or "已接通"
PASS fog-desktop: services — reading status opens no microphone
PASS fog-desktop: a voice is applied through the existing flow
PASS fog-desktop: settings still says a change takes effect at the next call
PASS fog-desktop: call line shows 本次通话 voice from the session answer
PASS fog-desktop: subtitles still show beside it
PASS fog-desktop: a choice made during the call does not change this call
PASS fog-desktop: ending the call releases the microphone and drops the pin
PASS fog-desktop: the next call shows the new voice
PASS fog-desktop: 500 after filing — says it may be registered and to refresh first
PASS fog-desktop: offers 刷新列表 and words a second registration as a checked choice
PASS fog-desktop: the list is not re-read or re-registered behind your back
PASS fog-desktop: refreshing names the new numbered entry
PASS fog-desktop: the numbered entry is marked as missing local metadata
PASS fog-desktop: after it is found the cautious button goes away
PASS moon-phone: services — TTS row says configured + health probe reachable
PASS moon-phone: services — ASR row claims no probe it does not have
PASS moon-phone: services — no voice row says "尚未接通" or "已接通"
PASS moon-phone: services — reading status opens no microphone
PASS moon-phone: a voice is applied through the existing flow
PASS moon-phone: settings still says a change takes effect at the next call
PASS moon-phone: call line shows 本次通话 voice from the session answer
PASS moon-phone: subtitles still show beside it
PASS moon-phone: a choice made during the call does not change this call
PASS moon-phone: ending the call releases the microphone and drops the pin
PASS moon-phone: the next call shows the new voice
PASS moon-phone: 500 after filing — says it may be registered and to refresh first
PASS moon-phone: offers 刷新列表 and words a second registration as a checked choice
PASS moon-phone: the list is not re-read or re-registered behind your back
PASS moon-phone: refreshing names the new numbered entry
PASS moon-phone: the numbered entry is marked as missing local metadata
PASS moon-phone: after it is found the cautious button goes away
PASS fog-phone: services — TTS row says configured + health probe reachable
PASS fog-phone: services — ASR row claims no probe it does not have
PASS fog-phone: services — no voice row says "尚未接通" or "已接通"
PASS fog-phone: services — reading status opens no microphone
PASS fog-phone: a voice is applied through the existing flow
PASS fog-phone: settings still says a change takes effect at the next call
PASS fog-phone: call line shows 本次通话 voice from the session answer
PASS fog-phone: subtitles still show beside it
PASS fog-phone: a choice made during the call does not change this call
PASS fog-phone: ending the call releases the microphone and drops the pin
PASS fog-phone: the next call shows the new voice
PASS fog-phone: 500 after filing — says it may be registered and to refresh first
PASS fog-phone: offers 刷新列表 and words a second registration as a checked choice
PASS fog-phone: the list is not re-read or re-registered behind your back
PASS fog-phone: refreshing names the new numbered entry
PASS fog-phone: the numbered entry is marked as missing local metadata
PASS fog-phone: after it is found the cautious button goes away
PASS status down: TTS "已配置 · 合成服务这会儿暂不可用"
PASS status down: ASR row honest
PASS status off: TTS "未配置 · 这台服务没有语音配置"
PASS status off: ASR row honest
PASS status no-route: TTS "这台服务没有语音状态接口"
PASS status no-route: ASR row honest
PASS status unknown-500: TTS "状态未知 · 这次没读到语音状态"
PASS status unknown-500: ASR row honest
PASS status unknown-net: TTS "状态未知 · 这次没读到语音状态"
PASS status unknown-net: ASR row honest
PASS session without voice: "声音未说明", not the settings choice
PASS session voice "default": shown as 默认声音
PASS dropped answer: may be registered, refresh first
PASS dropped answer: refresh finds the numbered entry
PASS 503: keeps the server words and adds the refresh advice
PASS 503: refresh finds nothing new and says to wait before registering again
PASS 503: the checked retry registers once and the take is gone
PASS recording: microphone live while recording
PASS recording: stop keeps the take and releases the microphone
PASS recording: cancel releases the microphone
PASS demo: zero /api requests from settings and the conversation
90/90 passed
+1
View File
@@ -0,0 +1 @@
hel903 mock on 8901 pid 2314388
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 865 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 880 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 856 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 852 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 861 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

+10
View File
@@ -0,0 +1,10 @@
> cybergril-web@0.1.0 lint
> eslint src
/home/xiaomo/multica_workspaces/hello-af23464d222e/hel-907-47adf6961f8a/workdir/CyberGril/web/src/chat/ChatPanel.tsx
252:100 warning The ref value 'fullButton.current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy 'fullButton.current' to a variable inside the effect, and use that variable in the cleanup function react-hooks/exhaustive-deps
✖ 1 problem (0 errors, 1 warning)
+4
View File
@@ -0,0 +1,4 @@
> cybergril-web@0.1.0 typecheck
> tsc --noEmit
+26
View File
@@ -0,0 +1,26 @@
> cybergril-web@0.1.0 test
> vitest run
RUN v3.1.2 /home/xiaomo/multica_workspaces/hello-af23464d222e/hel-907-47adf6961f8a/workdir/CyberGril/web
✓ tests/r3memory.test.ts (5 tests) 8ms
✓ tests/review878_late_cleanup.test.ts (1 test) 8ms
✓ tests/hel903_voice_rework.test.ts (11 tests) 14ms
✓ tests/hel879_frames.test.ts (10 tests) 21ms
✓ tests/real.test.ts (3 tests) 11ms
✓ tests/inbox.test.ts (13 tests) 24ms
✓ tests/domain.test.ts (12 tests) 9ms
✓ tests/hel898_agent_left.test.ts (7 tests) 26ms
✓ tests/reading.test.ts (11 tests) 46ms
✓ tests/r2wiring.test.ts (11 tests) 27ms
✓ tests/voice.test.ts (45 tests) 76ms
✓ tests/hel900_custom_voice.test.ts (19 tests) 530ms
✓ reference audio becomes the WAV the server accepts > refuses what the server would refuse, before sending anything 481ms
Test Files 12 passed (12)
Tests 148 passed (148)
Start at 19:56:25
Duration 837ms (transform 784ms, setup 0ms, collect 1.81s, tests 800ms, environment 7ms, prepare 522ms)
@@ -0,0 +1 @@
需求结构检查通过:60项;来源和覆盖完整。仍须人工核对授权语义与实际体验。
@@ -0,0 +1 @@
需求结构检查通过:60项;来源和覆盖完整。仍须人工核对授权语义与实际体验。
@@ -0,0 +1 @@
需求结构检查通过:60项;来源和覆盖完整。仍须人工核对授权语义与实际体验。
@@ -0,0 +1 @@
需求结构检查通过:60项;来源和覆盖完整。仍须人工核对授权语义与实际体验。
Binary file not shown.

After

Width:  |  Height:  |  Size: 381 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.
@@ -0,0 +1,73 @@
{
"cgId": "cg-f2ec321d",
"selection": {
"voice": "cg-f2ec321d",
"label": "hel907测试声",
"updated_at": 1793189770791
},
"checks": 14,
"passed": 13,
"netEvents": [
{
"url": "https://192.168.200.12:8361/api/health",
"status": 200,
"requestId": "2325794.8",
"ts": 1793189748990
},
{
"url": "https://192.168.200.12:8361/api/companion",
"status": 200,
"requestId": "2325794.10",
"ts": 1793189749002
},
{
"url": "https://192.168.200.12:8361/api/messages?limit=200",
"status": 200,
"requestId": "2325794.11",
"ts": 1793189749004
},
{
"url": "https://192.168.200.12:8361/api/health",
"status": 200,
"requestId": "2325794.42",
"ts": 1793189750743
},
{
"url": "https://192.168.200.12:8361/api/persona",
"status": 200,
"requestId": "2325794.43",
"ts": 1793189750747
},
{
"url": "https://192.168.200.12:8361/api/voice/voices",
"status": 200,
"requestId": "2325794.44",
"ts": 1793189765809
},
{
"url": "https://192.168.200.12:8361/api/voice/voices",
"status": 200,
"requestId": "2325794.49",
"ts": 1793189767243
},
{
"url": "https://192.168.200.12:8361/api/messages?limit=50",
"status": 200,
"requestId": "2325794.52",
"ts": 1793189769032
},
{
"url": "https://192.168.200.12:8361/api/voice/preview",
"status": 200,
"requestId": "2325794.51",
"ts": 1793189770572
},
{
"url": "https://192.168.200.12:8361/api/voice/selection",
"status": 200,
"requestId": "2325794.57",
"ts": 1793189770789
}
],
"previewFile": "/tmp/multica-task-366716746/opencode/webflow/out/preview-cg-f2ec321d.wav"
}
+167
View File
@@ -0,0 +1,167 @@
# HEL-907 · 网页自定义声音与三通真实交谈测试窗口记录(2026-10-28)
> 授权:白栖知主卡 HEL-797 评论 `01a18246-672a-7a19-9e8a-69c6f547a232`(2026-10-28 11:30 UTC)
> 「同意这轮测试」,批准《HEL-797-自定义声音实测安排.md》(评论 `01a18012-c208-7586-b87e-99f342849721`
> 附件 `01a18012-c1f5-77da-b386-59af7d4c2916`)。
> 执行基准:`origin/hel-906-asr-usage-counting` @ `038f1eeae71a9f67362d4694548d7d8116e0e35f`
> (含 HEL-905 统一复审与 HEL-906 定点返工)。需求基准 v1.12/60 项;本卡无需求变更。
> 窗口(UTC):**布防 12:07:46 – 封账 12:26:18**(18 分 32 秒,首个真实出站为网页登记上传,
> 远未用满 2 小时;3 通通话用满即封账)。
## 0. 结论速览
| 项 | 结果 |
| --- | --- |
| 网页自定义声音全链(上传→cg-登记→真实TTS试听→应用) | ✅ 真网页+真面板+真TTS 完成(13/14 步通过,1 项为测试脚本自身取文件大小的笔误,证据音频有效) |
| 下一通 worker 实用音色=会话 `voice` 字段 | ✅ call1/call2 `voice=cg-f2ec321d`,TTS 实际以该音色合成(tts.log) |
| 通话中改选不换声、下一通生效 | ✅ call2 通话中改选 rain:本通 worker 状态文件钉在 cg-f2ec321d;call3 `voice=rain` 生效 |
| 文字输入打断在播语音 | ❌ **发现真实缺陷**:文字轮被取消(user 行 `cancelled`),语音继续播完(约 32 秒),文字未获回复(§5) |
| 回放打断(真实 WebRTC 路径) | ⚠️ `turn_cancel` 真实发生(FunASR 真实识别回放语音),但本轮**未取得帧级停声时延**(§6) |
| 真实用户麦克风打断时延 | ❌ 未测(无真人发声;D3 用户设备动作,§8 交接) |
| 全部上限 | ✅ 全部在上限内,零付费支出(§7) |
| 共享注册表回收/服务恢复 | ✅ cg- 条目与样音频逐条回收,9880/8090 按窗口前状态停回,端口全清(§8) |
## 1. 构建(独立复跑,本地离线)
- `npm ci`(既有锁文件,已获批):176 包。
- `typecheck` 0 错;`lint` 0 错 1 警(`web/src/chat/ChatPanel.tsx:252` react-hooks 既有警告,非本卡引入);
`vitest` **148/148**;`build` 成功(产物已用于实测部署)。
- 浏览器脚本(本机既有 Playwright Chromium 156.0.8078.4,未下载任何浏览器;为使其可运行,
以 `apt-get download`+`dpkg-deb -x` 将 Ubuntu jammy 的运行时 GUI 库解压到用户目录并
`LD_LIBRARY_PATH` 加载——未安装系统包、未动系统信任库、无 root):
- `hel900_shots.mjs` **83/83**(1 处最小脚本适配:登记 503 后的界面自 HEL-903 起进入
「可能已登记→先刷新」状态,原脚本第 142 行直接双击「登记这段声音」在新界面下必然
扑空;按现行为改为「刷新列表→确认没有,再登记」后再双击,检查意图不变。产品代码零改动)。
- `hel903_shots.mjs` **90/90**(零改动)。
- 日志与截图:`docs/rework/hel907/build/`、`docs/rework/hel907/web/`。
## 2. 部署布局(全部独立,已全部撤除)
| 组件 | 端口/路径 | 说明 |
| --- | --- | --- |
| 统一实例(同进程双入口) | HTTP 8360 + HTTPS 8361 | `serve_dual_8360_8361.py`,隔离数据 `/opt/cybergril-hel907/data/`;Python 只读复用 HEL-879 `.venv311`(requirements.lock 与 038f1ee 逐字一致) |
| WSS TLS 桥 | 8363 → 127.0.0.1:7880 | 沿用 `/opt/cybergril-voice-certs/` 既有证书 |
| 专属 worker | 健康口 8082 | `/opt/cybergril-hel907/worker/`(独立 env/状态文件/日志),ASR 账本独立 `asr-usage.jsonl` |
| 共享 TTS 9880 / 面板 8090 | — | 窗口前均为**停机**;窗口内临时按其 README 运行方式启动,结束后按快照停回 |
| 预算布防 | — | `models.yaml`:dialogue 20/total 20/60000 tokens,其余 0;`CYBERGRIL_SEMANTIC=stub`(嵌入 0);布防前 worker 以 cap=0 验证 fail-closed,12:07:46 布防 `hel907-20261028-a`(2400s/6 次重连每通) |
| 测试档案 | — | 隔离实例自建测试伴侣「小测」,未触碰任何真实档案 |
## 3. 真网页链路(真实浏览器 → HTTPS 8361 → 真实 API → 真实面板/TTS)
真浏览器(本地 Chromium,接受自签证书与人工「高级→继续」同姿态)驱动真实页面完成:
1. 设置→她的声音→上传参考音频 `female_soft.wav`(上传前 sha256 只读核对
`4a65d170…d4f687`、341192 字节,与清单一致;浏览器端真实解码转 16kHz 单声道 WAV);
2. 填写参考文字(取自 voices.json 该条目既有 prompt_text,**未用转写**,登记转写 ASR=0)
与名称「hel907测试声」→ **登记成功 `cg-f2ec321d`**(共享注册表唯一写者 8090 面板;
上传出站 1 次);
3. **真实 TTS 试听**:现场合成 24kHz/3.72s WAV,页面真实播放,响应体已存证
`web/preview-cg-f2ec321d.wav`(出站 2 次含一次脚本迭代重试,均计数);
4. **应用**:`/api/voice/selection` = `cg-f2ec321d`,界面如实显示「下一次通话生效」。
截图逐步留证(`docs/rework/hel907/web/*.png`),网络事件清单 `web/webflow-result.json`。
## 4. 三通真实通话(预录语音回放经真实 WebRTC;顺序执行、不重叠)
| 通 | 内容 | 关键结果 |
| --- | --- | --- |
| call1 | 登记后首通:两轮完整对话 + 第三轮文字打断尝试 + 挂断 | `voice=cg-f2ec321d`;两轮 `turn_end`;字幕 seq 单调;回流音频 93.1s 落盘;DELETE 200、房间真删、删后仅 2 帧在途(约 20ms) |
| call2 | 通话中经 API 改选内置 rain | 会话 `voice=cg-f2ec321d`;改选 200;**本通 worker 状态文件钉在 cg-f2ec321d**(通话窗口持有语义成立);挂断后结算 |
| call3 | 下一通生效验证 + 回放打断 | **会话 `voice=rain`**(下一通生效);回放打断产生真实 `turn_cancel`;挂断清理同 call1 |
TTS 实际音色核对:`/opt/voice-agent/cosyvoice/tts.log` 窗口内 11 段合成全部带
`voice=cg-f2ec321d`(call1/2)/ `voice=rain`(call3),与会话响应逐一对应。
## 5. 缺陷发现:文字输入打断在播语音(真实复现,含完整证据链)
**现象**(call1 第三轮,字幕/数据库/网络三层对齐):
- 她正在语音回复(`turn_start` → `assistant_interim` 持续流式中)时,文字通道
POST `/api/chat`(200);
- 她的语音**没有停止**:此后 ~32 秒音频帧连续到达(100 帧/秒不间断),旧回复播完;
- 数据库 `chat_message`:**文字轮 user 行 id=6 `status=cancelled`**,语音轮
id=5/id=8 `status='sent'` —— 用户那条文字被静默丢弃、无任何回复;
- api.log:文字 POST 之后 worker 侧又发起了第 5 次 `/api/chat`(同 turn_id 重试)。
**机制**(源码级):服务端取消机制本身方向正确(app.py:577-581 新轮 set 旧轮
cancel)。但语音轮被文字轮取消后,worker 的 SSE 流被服务端按取消收尾,适配器
`llm_chat_api.py` 将其当作连接异常,经 livekit APIConnectOptions **静默重试同一
turn_id**:重试的 chat() 取消了当时活动的**文字轮**(文字行→cancelled),随后语音轮
完整重新生成并播完。`llm_chat_api.py:90` 的 `_retry_on_chunk_sent = False` 注释称
「输出后绝不自动重试」,但该守卫从未被置真——**chips 已发出后仍会重试**,注释与实现
相反;HEL-879 观察到的「语音取消文字」竞态与本轮「重试取消文字」是同一缺陷家族的
两次不同投影。用户可感知后果:**她在说话时发文字,既不会停她的语音,文字也会消失**。
证据:`window/call1.subtitles.jsonl`(t0=1793189878442 前后)、`window/call1.json`、
`window/api.log`(第 112-129 行)、DB 快照(call1.json budget 段与上文行号)。
**本卡不修**(属语音/文字互打断核心语义,交回总管安排修复与复测)。
## 6. 打断停声时延:本轮未取得(如实)
- call3 回放打断:`turn_cancel` 由真实链路产生(FunASR 真实识别了回放语音并出
user_final,VAD/取消链路真实工作)。
- 但**帧级「旧声停止」时延未取得**,两个原因都有证据:
1. 打断源 `sunwukong.wav` 实测过轻(16kHz/13.4s,逐 50ms 窗 RMS 低于 VAD 噪声门限,
离线分析 onset 无检出)→ VAD 直至回放结束、2-pass 离线纠错 final(发布后 16.05s)
才判停,这不是真实人声的起声时延;
2. 被打断的旧轮当时**无可闻旧声**:其 LLM 流在打断前卡死(interim 重复不增长),
对回流音频逐帧能量分析(`call3.agent.wav` × `call3.frames.json` 同钟对齐)显示
cancel 前后 ±25s 内旧语音能量段缺失,cancel 后 8.9s 才出现新回复语音——没有
「正在播的旧声」可供量停。
- 同钟量测方法已备好并验证可用(客户端毫秒时钟统一记录发布帧与到达帧;
`call1.frames.json`/`call3.frames.json` 即完整时间轴),下轮配响亮短促打断源即可
直接出数。**不得把本轮数字当作 ~1 秒停声结论**。
- 真实用户麦克风方向(真人开口 T0 + 同机分轨):无真人发声,未测(§8)。
## 7. 用量账(含失败/取消口径;封账后不重开)
| 类别 | 实际用量 | 上限 |
| --- | --- | --- |
| 时窗 | 18 分 32 秒 | ≤2 小时 |
| 实际通话 | 3 通(顺序) | ≤3 |
| 建房 | 4 次(3 通 + 1 次客户端证书信任遗漏导致的连接失败空会话,已 DELETE 结清) | ≤6 |
| LLM | **8 请求 / 23,958 tokens**(含 call1 缺陷链的取消轮与重试轮) | ≤20 / ≤60000 |
| 嵌入 | 0(`semantic_backend=stub` 全程) | 0 |
| 登记上传出站 | 1 | ≤3 |
| 登记转写 ASR | 0(参考文字手填) | ≤3 |
| 试听 TTS | 2 | ≤10 |
| 通话 TTS 段 | 11(tts.log 窗口内 13 段 − 2 试听) | ≤40 |
| 连续通话 ASR | **195.16s**(保守=确证 195.16s,逐通话 95.18/41.34/58.64s + 空会话 0) | ≤2400s |
| ASR 连接重试 | 0 | ≤6/通 |
| 新增付费支出 | 0 | 0 |
## 8. 清理、恢复与回收(逐项核对)
- 8360/8361/8363/8082 全停;LiveKit 房间清空(`rooms: []`)。
- 共享 TTS 9880、面板 8090 按窗口前快照**停回停机**(精确 PID 终止,未用 fuser -k);
GPU 回 97MiB;8300/8310/8320/8350 原样运行,8340 保持停机,7880/10095 未动。
- `cg-f2ec321d` 经 8090 自有删除入口回收:删除前后面板列表与 voices.json 快照留证,
`voice_samples/cg-*.wav` 无残留;**11 支内置与全局默认零变化**(前后 JSON 比对)。
- 测试档案/账本/流水全部留在 `/opt/cybergril-hel907/`(隔离实例数据,未触碰
`/opt/cybergril-hel879` 与任何既有实例);证据包
`/opt/cybergril-hel907/hel907-evidence-20261028.tar.gz`
sha256 `37ee18818d46b7d605cb4b0fac924a401138fc17a50520d4af6cc58b6082e07e`。
- 回滚:删除 `/opt/cybergril-hel907` 即完全退场;共享注册表已按上条真实回收
(未拿 git 回退代替)。
## 9. 未测 / 承接(如实)
- **真实用户麦克风打断时延**(D3 用户动作):需真人在同一时间轴发声+听声。入口已备好:
任意局域网设备浏览器打开 `https://192.168.200.12:8361`(当前已撤防,需下轮窗口重新
部署),证书「高级→继续」两处(8361/8363)、允许麦克风,对她说话打断即可;建议动作
≤2 分钟/次。本轮不自行打开任何用户设备。
- iOS Safari/安卓 Chrome 真机路径:未测。
- 帧级停声时延:方法已验证,待响亮打断源 + 她正在可闻说话的时机(§6)。
- §5 缺陷的修复与复测:交回总管(涉及 worker 适配器重试守卫与文字/语音互打断语义,
本卡按边界不修)。
- 回复质量观察(非链路故障):call1 出现一条对「睡觉」话题的擦边回复,与测试档案
boundary 文案相关,记录备查。
## 10. 需求与检查
- 基准 v1.12/60 项;本卡零需求变更(无 GOV 记录)。
- `python3 scripts/check_requirements.py --base-ref origin/main` 与
`--base-ref 038f1ee`(含 `--handoff docs/requirements/handoff-HEL-907.json`)通过,
日志随交付评论。
- 关联要求:CG-006/009/010/013–016/018–021、AM-001、GOV-001–006、DEL-001(覆盖关系见
handoff JSON)。
+163
View File
@@ -0,0 +1,163 @@
INFO: Started server process [51550]
INFO: Started server process [51550]
INFO: Uvicorn running on http://0.0.0.0:8360 (Press CTRL+C to quit)
INFO: Uvicorn running on https://0.0.0.0:8361 (Press CTRL+C to quit)
INFO: 127.0.0.1:35146 - "GET /api/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:54282 - "GET /api/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:55670 - "GET /api/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:55684 - "GET /api/voice/status HTTP/1.1" 200 OK
INFO: 127.0.0.1:55692 - "GET /api/voice/voices HTTP/1.1" 200 OK
INFO: 127.0.0.1:54786 - "POST /api/companion HTTP/1.1" 201 Created
INFO: 127.0.0.1:54794 - "GET /api/health HTTP/1.1" 200 OK
INFO: 192.168.200.13:37764 - "GET / HTTP/1.1" 200 OK
INFO: 192.168.200.13:37772 - "GET /assets/index-B8TdHoQm.css HTTP/1.1" 200 OK
INFO: 192.168.200.13:37764 - "GET /assets/index-ba4PURHH.js HTTP/1.1" 200 OK
INFO: 192.168.200.13:37764 - "GET /assets/her-room.jpg HTTP/1.1" 200 OK
INFO: 192.168.200.13:37772 - "GET /assets/her-talk.jpg HTTP/1.1" 200 OK
INFO: 192.168.200.13:37764 - "GET /api/health HTTP/1.1" 200 OK
INFO: 192.168.200.13:37772 - "GET /favicon.ico HTTP/1.1" 404 Not Found
INFO: 192.168.200.13:37772 - "GET /api/companion HTTP/1.1" 200 OK
INFO: 192.168.200.13:37772 - "GET /api/messages?limit=200 HTTP/1.1" 200 OK
INFO: 192.168.200.13:37772 - "GET /assets/icons.svg HTTP/1.1" 200 OK
INFO: 192.168.200.13:37788 - "GET /api/health HTTP/1.1" 200 OK
INFO: 192.168.200.13:37788 - "GET /api/persona HTTP/1.1" 200 OK
INFO: 192.168.200.13:35790 - "GET /api/messages?limit=50 HTTP/1.1" 200 OK
INFO: 192.168.200.13:36634 - "GET / HTTP/1.1" 200 OK
INFO: 192.168.200.13:36634 - "GET /assets/index-ba4PURHH.js HTTP/1.1" 200 OK
INFO: 192.168.200.13:36650 - "GET /assets/index-B8TdHoQm.css HTTP/1.1" 200 OK
INFO: 192.168.200.13:36634 - "GET /assets/her-room.jpg HTTP/1.1" 200 OK
INFO: 192.168.200.13:36650 - "GET /assets/her-talk.jpg HTTP/1.1" 200 OK
INFO: 192.168.200.13:36650 - "GET /api/health HTTP/1.1" 200 OK
INFO: 192.168.200.13:36634 - "GET /favicon.ico HTTP/1.1" 404 Not Found
INFO: 192.168.200.13:36634 - "GET /api/companion HTTP/1.1" 200 OK
INFO: 192.168.200.13:36634 - "GET /api/messages?limit=200 HTTP/1.1" 200 OK
INFO: 192.168.200.13:36634 - "GET /assets/icons.svg HTTP/1.1" 200 OK
INFO: 192.168.200.13:34282 - "GET / HTTP/1.1" 200 OK
INFO: 192.168.200.13:34282 - "GET /assets/index-ba4PURHH.js HTTP/1.1" 200 OK
INFO: 192.168.200.13:34296 - "GET /assets/index-B8TdHoQm.css HTTP/1.1" 200 OK
INFO: 192.168.200.13:34296 - "GET /assets/her-talk.jpg HTTP/1.1" 200 OK
INFO: 192.168.200.13:34282 - "GET /assets/her-room.jpg HTTP/1.1" 200 OK
INFO: 192.168.200.13:34296 - "GET /favicon.ico HTTP/1.1" 404 Not Found
INFO: 192.168.200.13:34282 - "GET /api/health HTTP/1.1" 200 OK
INFO: 192.168.200.13:34282 - "GET /api/companion HTTP/1.1" 200 OK
INFO: 192.168.200.13:34282 - "GET /api/messages?limit=200 HTTP/1.1" 200 OK
INFO: 192.168.200.13:34282 - "GET /assets/icons.svg HTTP/1.1" 200 OK
INFO: 192.168.200.13:52250 - "GET /api/health HTTP/1.1" 200 OK
INFO: 192.168.200.13:52250 - "GET /api/persona HTTP/1.1" 200 OK
INFO: 192.168.200.13:34538 - "GET /api/voice/voices HTTP/1.1" 200 OK
INFO: 192.168.200.13:39392 - "GET / HTTP/1.1" 200 OK
INFO: 192.168.200.13:39392 - "GET /assets/index-ba4PURHH.js HTTP/1.1" 200 OK
INFO: 192.168.200.13:39396 - "GET /assets/index-B8TdHoQm.css HTTP/1.1" 200 OK
INFO: 192.168.200.13:39392 - "GET /assets/her-room.jpg HTTP/1.1" 200 OK
INFO: 192.168.200.13:39396 - "GET /assets/her-talk.jpg HTTP/1.1" 200 OK
INFO: 192.168.200.13:39392 - "GET /api/health HTTP/1.1" 200 OK
INFO: 192.168.200.13:39396 - "GET /favicon.ico HTTP/1.1" 404 Not Found
INFO: 192.168.200.13:39396 - "GET /api/companion HTTP/1.1" 200 OK
INFO: 192.168.200.13:39396 - "GET /api/messages?limit=200 HTTP/1.1" 200 OK
INFO: 192.168.200.13:39396 - "GET /assets/icons.svg HTTP/1.1" 200 OK
INFO: 192.168.200.13:39402 - "GET /api/health HTTP/1.1" 200 OK
INFO: 192.168.200.13:39402 - "GET /api/persona HTTP/1.1" 200 OK
INFO: 192.168.200.13:39268 - "GET /api/voice/voices HTTP/1.1" 200 OK
INFO: 192.168.200.13:39268 - "POST /api/voice/voices?label=hel907%E6%B5%8B%E8%AF%95%E5%A3%B0&prompt_text=%E8%BF%99%E7%82%B9%E6%88%91%E8%AF%B4%E4%B8%80%E4%B8%8B%EF%BC%8C%E5%B0%B1%E6%98%AF%E5%9B%A0%E4%B8%BA%E9%82%A3%E4%B8%AA%E5%B0%B1%E6%98%AF%E6%91%A9%E6%A0%B9%E8%B1%AA%E6%B3%BD%E5%B0%94%E8%BF%99%E6%9C%AC%E5%84%BF%E9%87%91%E9%92%B1%E5%BF%83%E7%90%86%E5%AD%A6%E3%80%82%E5%85%B6%E5%AE%9E%E5%9C%A8%E6%88%91%E4%BB%AC%E8%BF%99%E8%A1%8C%E4%B8%9A%E9%87%8C%E4%B9%9F%E7%AE%97%E4%B8%80%E6%9C%AC%E5%BE%88%E6%9C%89%E5%90%8D%E5%90%8D%E7%9A%84%E4%B9%A6%E4%BA%86%E3%80%82%E5%B0%B1%E6%88%91%E4%B9%8B%E5%89%8D%E4%B9%9F%E8%AF%BB%E8%BF%87%E3%80%82%E7%84%B6%E5%90%8E%E4%BD%A0%E8%AF%B4%E5%88%B0%E8%BF%99%E7%82%B9%E5%95%8A%EF%BC%8C%E8%AE%A9%E6%88%91%E6%83%B3%E8%B5%B7%E6%9D%A5%E4%BB%96%E8%BF%99%E6%9C%AC%E4%B9%A6%E9%87%8C%E8%BF%98%E6%8C%BA%E3%80%82&allow_asr=false HTTP/1.1" 201 Created
INFO: 192.168.200.13:39268 - "GET /api/voice/voices HTTP/1.1" 200 OK
INFO: 192.168.200.13:39268 - "GET /api/messages?limit=50 HTTP/1.1" 200 OK
INFO: 192.168.200.13:34666 - "GET /api/messages?limit=50 HTTP/1.1" 200 OK
INFO: 192.168.200.13:50186 - "GET /api/messages?limit=50 HTTP/1.1" 200 OK
INFO: 192.168.200.13:49688 - "GET /api/messages?limit=50 HTTP/1.1" 200 OK
INFO: 192.168.200.13:49678 - "POST /api/voice/preview HTTP/1.1" 200 OK
INFO: 192.168.200.13:49678 - "GET /favicon.ico HTTP/1.1" 404 Not Found
INFO: 192.168.200.13:56190 - "GET / HTTP/1.1" 200 OK
INFO: 192.168.200.13:56196 - "GET /assets/index-B8TdHoQm.css HTTP/1.1" 200 OK
INFO: 192.168.200.13:56190 - "GET /assets/index-ba4PURHH.js HTTP/1.1" 200 OK
INFO: 192.168.200.13:56190 - "GET /assets/her-room.jpg HTTP/1.1" 200 OK
INFO: 192.168.200.13:56196 - "GET /assets/her-talk.jpg HTTP/1.1" 200 OK
INFO: 192.168.200.13:56190 - "GET /api/health HTTP/1.1" 200 OK
INFO: 192.168.200.13:56196 - "GET /favicon.ico HTTP/1.1" 404 Not Found
INFO: 192.168.200.13:56196 - "GET /api/companion HTTP/1.1" 200 OK
INFO: 192.168.200.13:56196 - "GET /api/messages?limit=200 HTTP/1.1" 200 OK
INFO: 192.168.200.13:56196 - "GET /assets/icons.svg HTTP/1.1" 200 OK
INFO: 192.168.200.13:56198 - "GET /api/health HTTP/1.1" 200 OK
INFO: 192.168.200.13:56198 - "GET /api/persona HTTP/1.1" 200 OK
INFO: 192.168.200.13:42546 - "GET /api/voice/voices HTTP/1.1" 200 OK
INFO: 192.168.200.13:42546 - "GET /api/voice/voices HTTP/1.1" 200 OK
INFO: 192.168.200.13:42546 - "GET /api/messages?limit=50 HTTP/1.1" 200 OK
INFO: 192.168.200.13:40396 - "GET /api/messages?limit=50 HTTP/1.1" 200 OK
INFO: 192.168.200.13:55742 - "GET /api/messages?limit=50 HTTP/1.1" 200 OK
INFO: 192.168.200.13:52300 - "GET /api/messages?limit=50 HTTP/1.1" 200 OK
INFO: 192.168.200.13:53190 - "GET /api/messages?limit=50 HTTP/1.1" 200 OK
INFO: 192.168.200.13:41864 - "GET /api/voice/selection HTTP/1.1" 200 OK
INFO: 192.168.200.13:48644 - "GET / HTTP/1.1" 200 OK
INFO: 192.168.200.13:48652 - "GET /assets/index-B8TdHoQm.css HTTP/1.1" 200 OK
INFO: 192.168.200.13:48644 - "GET /assets/index-ba4PURHH.js HTTP/1.1" 200 OK
INFO: 192.168.200.13:48652 - "GET /assets/her-talk.jpg HTTP/1.1" 200 OK
INFO: 192.168.200.13:48644 - "GET /assets/her-room.jpg HTTP/1.1" 200 OK
INFO: 192.168.200.13:48652 - "GET /favicon.ico HTTP/1.1" 404 Not Found
INFO: 192.168.200.13:48644 - "GET /api/health HTTP/1.1" 200 OK
INFO: 192.168.200.13:48644 - "GET /api/companion HTTP/1.1" 200 OK
INFO: 192.168.200.13:48644 - "GET /api/messages?limit=200 HTTP/1.1" 200 OK
INFO: 192.168.200.13:48644 - "GET /assets/icons.svg HTTP/1.1" 200 OK
INFO: 192.168.200.13:53266 - "GET /api/health HTTP/1.1" 200 OK
INFO: 192.168.200.13:53266 - "GET /api/persona HTTP/1.1" 200 OK
INFO: 192.168.200.13:35132 - "GET /api/voice/voices HTTP/1.1" 200 OK
INFO: 192.168.200.13:35132 - "GET /api/voice/voices HTTP/1.1" 200 OK
INFO: 192.168.200.13:35136 - "GET /api/messages?limit=50 HTTP/1.1" 200 OK
INFO: 192.168.200.13:35132 - "POST /api/voice/preview HTTP/1.1" 200 OK
INFO: 192.168.200.13:35132 - "GET /favicon.ico HTTP/1.1" 404 Not Found
INFO: 192.168.200.13:35132 - "POST /api/voice/selection HTTP/1.1" 200 OK
INFO: 192.168.200.13:59128 - "GET /api/voice/selection HTTP/1.1" 200 OK
INFO: 127.0.0.1:59706 - "POST /api/voice/session HTTP/1.1" 201 Created
INFO: 127.0.0.1:34604 - "DELETE /api/voice/session/8GoWvxeEizUDyuqJJrcf0MFl HTTP/1.1" 200 OK
INFO: 127.0.0.1:53630 - "POST /api/voice/session HTTP/1.1" 201 Created
INFO: 127.0.0.1:55398 - "GET /api/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:55398 - "POST /api/chat HTTP/1.1" 200 OK
memory compression failed: memory_id=2
INFO: 127.0.0.1:36786 - "GET /api/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:36786 - "POST /api/chat/received HTTP/1.1" 200 OK
INFO: 127.0.0.1:35066 - "GET /api/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:35066 - "POST /api/chat HTTP/1.1" 200 OK
INFO: 127.0.0.1:38996 - "GET /api/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:38996 - "POST /api/chat/received HTTP/1.1" 200 OK
memory compression failed: memory_id=2
INFO: 127.0.0.1:38996 - "GET /api/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:38996 - "POST /api/chat HTTP/1.1" 200 OK
INFO: 127.0.0.1:39004 - "GET /api/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:39008 - "POST /api/chat HTTP/1.1" 200 OK
INFO: 127.0.0.1:38996 - "GET /api/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:38996 - "POST /api/chat HTTP/1.1" 200 OK
memory compression failed: memory_id=2
INFO: 127.0.0.1:48932 - "GET /api/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:48932 - "POST /api/chat/received HTTP/1.1" 200 OK
INFO: 127.0.0.1:48938 - "DELETE /api/voice/session/8z_mtXElLBoxPfHd8G0rPZjt HTTP/1.1" 200 OK
memory compression failed: memory_id=1
memory compression failed: memory_id=1
memory compression failed: memory_id=1
memory compression failed: memory_id=4
memory compression failed: memory_id=4
memory compression failed: memory_id=4
INFO: 127.0.0.1:37118 - "POST /api/voice/session HTTP/1.1" 201 Created
INFO: 127.0.0.1:42646 - "GET /api/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:42646 - "POST /api/chat HTTP/1.1" 200 OK
memory compression failed: memory_id=3
INFO: 127.0.0.1:44680 - "GET /api/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:44680 - "POST /api/chat/received HTTP/1.1" 200 OK
INFO: 127.0.0.1:44690 - "POST /api/voice/selection HTTP/1.1" 200 OK
INFO: 127.0.0.1:44690 - "DELETE /api/voice/session/FnM8-yTH5keAHRRJiS-EJBwp HTTP/1.1" 200 OK
memory compression failed: memory_id=3
INFO: 127.0.0.1:48662 - "POST /api/voice/session HTTP/1.1" 201 Created
INFO: 127.0.0.1:60228 - "GET /api/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:60228 - "POST /api/chat HTTP/1.1" 200 OK
memory compression failed: memory_id=3
INFO: 127.0.0.1:37716 - "GET /api/health HTTP/1.1" 200 OK
INFO: 127.0.0.1:37716 - "POST /api/chat HTTP/1.1" 200 OK
memory compression failed: memory_id=6
INFO: 127.0.0.1:58382 - "DELETE /api/voice/session/Wnv2wpdoE6wpBN59NDJ1d8yo HTTP/1.1" 200 OK
memory compression failed: memory_id=6
memory compression failed: memory_id=6
memory compression failed: memory_id=5
memory compression failed: memory_id=5
memory compression failed: memory_id=5
memory compression failed: memory_id=8
INFO: Shutting down
INFO: Finished server process [51550]
INFO: Shutting down
INFO: Finished server process [51550]
@@ -0,0 +1,50 @@
{
"records": 51,
"parse_errors": 0,
"windows": {
"hel907-20261028-a": {
"audio_seconds": 195.161381,
"confirmed_audio_seconds": 195.161381,
"stopped": false,
"stop_reason": "",
"calls": {
"cg-voice-7pqdbsmq99": {
"streams": 1,
"connect_attempts": 0,
"connect_failures": 0,
"connect_retries": 0,
"audio_seconds": 0.0,
"confirmed_audio_seconds": 0.0,
"retry_pending": true
},
"cg-voice-1mrb1jwl35": {
"streams": 1,
"connect_attempts": 1,
"connect_failures": 0,
"connect_retries": 0,
"audio_seconds": 95.183847,
"confirmed_audio_seconds": 95.183847,
"retry_pending": true
},
"cg-voice-h9ncn972c6": {
"streams": 1,
"connect_attempts": 1,
"connect_failures": 0,
"connect_retries": 0,
"audio_seconds": 41.337176,
"confirmed_audio_seconds": 41.337176,
"retry_pending": true
},
"cg-voice-nr7g2y5nd6": {
"streams": 1,
"connect_attempts": 1,
"connect_failures": 0,
"connect_retries": 0,
"audio_seconds": 58.640358,
"confirmed_audio_seconds": 58.640358,
"retry_pending": true
}
}
}
}
}
+51
View File
@@ -0,0 +1,51 @@
{"kind":"call_start","call":"cg-voice-7pqdbsmq99","stream_seq":1,"window":"hel907-20261028-a","t":1793189792.659}
{"kind":"call_end","call":"cg-voice-7pqdbsmq99","reason":"error","audio_seconds":0.0,"confirmed_audio_seconds":0.0,"connect_attempts":0,"connect_failures":0,"connect_retries":0,"window":"hel907-20261028-a","t":1793189813.289}
{"kind":"call_start","call":"cg-voice-1mrb1jwl35","stream_seq":1,"window":"hel907-20261028-a","t":1793189817.273}
{"kind":"connect_attempt","call":"cg-voice-1mrb1jwl35","seq":1,"ok":true,"retry":false,"error":"","window":"hel907-20261028-a","t":1793189817.354}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.023499,"confirmed_seconds":4.990686,"frames":101,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189822.323}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.056373,"confirmed_seconds":5.023499,"frames":101,"bytes":161804,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189827.373}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.056311,"confirmed_seconds":5.056311,"frames":101,"bytes":161802,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189832.422}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.056311,"confirmed_seconds":5.056373,"frames":101,"bytes":161802,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189837.472}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.023499,"confirmed_seconds":5.056311,"frames":101,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189842.523}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.023498,"confirmed_seconds":4.990686,"frames":100,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189847.523}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.023499,"confirmed_seconds":5.056311,"frames":101,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189852.573}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.023498,"confirmed_seconds":4.990686,"frames":100,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189857.573}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.056373,"confirmed_seconds":5.056311,"frames":101,"bytes":161804,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189862.621}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.023499,"confirmed_seconds":5.056311,"frames":101,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189867.673}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.023498,"confirmed_seconds":4.990686,"frames":100,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189872.672}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.023499,"confirmed_seconds":5.056311,"frames":101,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189877.722}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.023498,"confirmed_seconds":4.990686,"frames":100,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189882.722}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.056311,"confirmed_seconds":5.056311,"frames":101,"bytes":161802,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189887.772}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.023499,"confirmed_seconds":5.056373,"frames":101,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189892.822}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.023498,"confirmed_seconds":4.990624,"frames":100,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189897.822}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.023499,"confirmed_seconds":5.056373,"frames":101,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189902.872}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":5.023498,"confirmed_seconds":4.990624,"frames":100,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189907.873}
{"kind":"audio","call":"cg-voice-1mrb1jwl35","seconds":4.596687,"confirmed_seconds":4.662374,"frames":62,"bytes":147094,"sample_rate":16000,"window":"hel907-20261028-a","t":1793189912.488}
{"kind":"call_end","call":"cg-voice-1mrb1jwl35","reason":"error","audio_seconds":95.183847,"confirmed_audio_seconds":95.183847,"connect_attempts":1,"connect_failures":0,"connect_retries":0,"window":"hel907-20261028-a","t":1793189912.488}
{"kind":"call_start","call":"cg-voice-h9ncn972c6","stream_seq":1,"window":"hel907-20261028-a","t":1793190088.943}
{"kind":"connect_attempt","call":"cg-voice-h9ncn972c6","seq":1,"ok":true,"retry":false,"error":"","window":"hel907-20261028-a","t":1793190089.007}
{"kind":"audio","call":"cg-voice-h9ncn972c6","seconds":5.023499,"confirmed_seconds":4.990686,"frames":101,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190093.993}
{"kind":"audio","call":"cg-voice-h9ncn972c6","seconds":5.056373,"confirmed_seconds":5.023499,"frames":101,"bytes":161804,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190099.044}
{"kind":"audio","call":"cg-voice-h9ncn972c6","seconds":5.056311,"confirmed_seconds":5.056311,"frames":101,"bytes":161802,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190104.094}
{"kind":"audio","call":"cg-voice-h9ncn972c6","seconds":5.056311,"confirmed_seconds":5.056373,"frames":101,"bytes":161802,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190109.144}
{"kind":"audio","call":"cg-voice-h9ncn972c6","seconds":5.023499,"confirmed_seconds":5.056311,"frames":101,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190114.193}
{"kind":"audio","call":"cg-voice-h9ncn972c6","seconds":5.023498,"confirmed_seconds":4.990686,"frames":100,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190119.195}
{"kind":"audio","call":"cg-voice-h9ncn972c6","seconds":5.023499,"confirmed_seconds":5.056311,"frames":101,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190124.244}
{"kind":"audio","call":"cg-voice-h9ncn972c6","seconds":5.056373,"confirmed_seconds":4.892186,"frames":86,"bytes":161804,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190128.309}
{"kind":"audio","call":"cg-voice-h9ncn972c6","seconds":1.017813,"confirmed_seconds":1.214813,"frames":5,"bytes":32570,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190130.308}
{"kind":"call_end","call":"cg-voice-h9ncn972c6","reason":"error","audio_seconds":41.337176,"confirmed_audio_seconds":41.337176,"connect_attempts":1,"connect_failures":0,"connect_retries":0,"window":"hel907-20261028-a","t":1793190130.309}
{"kind":"call_start","call":"cg-voice-nr7g2y5nd6","stream_seq":1,"window":"hel907-20261028-a","t":1793190148.354}
{"kind":"connect_attempt","call":"cg-voice-nr7g2y5nd6","seq":1,"ok":true,"retry":false,"error":"","window":"hel907-20261028-a","t":1793190148.438}
{"kind":"audio","call":"cg-voice-nr7g2y5nd6","seconds":5.023499,"confirmed_seconds":4.990686,"frames":101,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190153.404}
{"kind":"audio","call":"cg-voice-nr7g2y5nd6","seconds":5.056373,"confirmed_seconds":5.023499,"frames":101,"bytes":161804,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190158.456}
{"kind":"audio","call":"cg-voice-nr7g2y5nd6","seconds":5.056311,"confirmed_seconds":5.056311,"frames":101,"bytes":161802,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190163.504}
{"kind":"audio","call":"cg-voice-nr7g2y5nd6","seconds":5.056311,"confirmed_seconds":5.056373,"frames":101,"bytes":161802,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190168.555}
{"kind":"audio","call":"cg-voice-nr7g2y5nd6","seconds":5.023499,"confirmed_seconds":5.056311,"frames":101,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190173.604}
{"kind":"audio","call":"cg-voice-nr7g2y5nd6","seconds":5.023498,"confirmed_seconds":4.990686,"frames":100,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190178.604}
{"kind":"audio","call":"cg-voice-nr7g2y5nd6","seconds":5.023499,"confirmed_seconds":5.056311,"frames":101,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190183.654}
{"kind":"audio","call":"cg-voice-nr7g2y5nd6","seconds":5.023498,"confirmed_seconds":4.990686,"frames":100,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190188.654}
{"kind":"audio","call":"cg-voice-nr7g2y5nd6","seconds":5.056373,"confirmed_seconds":5.056311,"frames":101,"bytes":161804,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190193.703}
{"kind":"audio","call":"cg-voice-nr7g2y5nd6","seconds":5.023499,"confirmed_seconds":5.056311,"frames":101,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190198.755}
{"kind":"audio","call":"cg-voice-nr7g2y5nd6","seconds":5.023498,"confirmed_seconds":4.990686,"frames":100,"bytes":160752,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190203.754}
{"kind":"audio","call":"cg-voice-nr7g2y5nd6","seconds":3.2505,"confirmed_seconds":3.316187,"frames":26,"bytes":104016,"sample_rate":16000,"window":"hel907-20261028-a","t":1793190206.549}
{"kind":"call_end","call":"cg-voice-nr7g2y5nd6","reason":"error","audio_seconds":58.640358,"confirmed_audio_seconds":58.640358,"connect_attempts":1,"connect_failures":0,"connect_retries":0,"window":"hel907-20261028-a","t":1793190206.549}
+1
View File
@@ -0,0 +1 @@
wss-bridge(PROPOSAL) tls ('0.0.0.0', 8363) -> 127.0.0.1:7880
Binary file not shown.
File diff suppressed because one or more lines are too long
+97
View File
@@ -0,0 +1,97 @@
{
"rounds": [
{
"play_label": "haimianbaobao",
"reply": {
"kind": "turn_end",
"speech_id": "speech_f0b3160be81e",
"reason": null
}
},
{
"play_label": "nezha",
"reply": {
"kind": "turn_end",
"speech_id": "speech_9ae41249c69d",
"reason": null
}
}
],
"text_interrupt": {
"outcome": "no-cancel",
"t0_text_post_ms": 1793189878442,
"cancel_ms": null,
"cancel_latency_s": null,
"old_audio_last_frame_ms": 1793189910457,
"old_audio_stop_latency_s": 32.015,
"frames_t0_plus1": 3202,
"text_http_status": 200
},
"hangup": {
"delete_status": 200,
"delete_body": {
"ended": true,
"room": "cg-voice-1mrb1jwl35"
},
"delete_ms": 1793189910465,
"agent_frames_after_delete": 2,
"room_removed": true
},
"call": {
"tag": "call1",
"session": {
"url": "wss://192.168.200.12:8363",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2aWRlbyI6eyJyb29tSm9pbiI6dHJ1ZSwicm9vbSI6ImNnLXZvaWNlLTFtcmIxandsMzUiLCJjYW5QdWJsaXNoIjp0cnVlLCJjYW5TdWJzY3JpYmUiOnRydWUsImNhblB1Ymxpc2hEYXRhIjp0cnVlfSwic3ViIjoidXNlci1jcXl3d3locSIsImlzcyI6ImRldmtleSIsIm5iZiI6MTc5MzE4OTgxNiwiZXhwIjoxNzkzMTkwMTE2LCJuYW1lIjoi55So5oi3In0.EoUQIq34zCLMpvEN2Ahb0WFxfxls-o-xa4B8GTyBjrY",
"room": "cg-voice-1mrb1jwl35",
"session_id": "8z_mtXElLBoxPfHd8G0rPZjt",
"agent_name": "cybergril-voice-agent",
"epoch": 1,
"expires_at": 1793190716678,
"voice": "cg-f2ec321d"
},
"session_voice": "cg-f2ec321d",
"subtitle_count": 189,
"seq_monotonic": true,
"agent_frames": 9313,
"agent_audio_seconds": 93.1,
"agent_audio_rate": 48000,
"agent_joined_ms": 1793189817292,
"agent_left_ms": null,
"subtitles_file": "/opt/cybergril-hel907/evidence/call1.subtitles.jsonl",
"frames_file": "/opt/cybergril-hel907/evidence/call1.frames.json",
"agent_audio_file": "/opt/cybergril-hel907/evidence/call1.agent.wav"
},
"budget_after": {
"at_ms": 1793189913005,
"token_usage": [
{
"day": "2026-10-28",
"scene": "dialogue_main",
"used": 14297
}
],
"request_usage": [
{
"day": "2026-10-28",
"category": "dialogue",
"requests": 5
}
],
"budget_total": [
{
"key": "total_requests",
"value": 5
},
{
"key": "total_tokens",
"value": 14297
}
]
},
"worker_state_after": {
"exists": true,
"content": {
"voice": "cg-f2ec321d"
}
}
}
@@ -0,0 +1,189 @@
{"v": 2, "seq": 1, "kind": "interim", "role": "user", "text": "没", "_at_ms": 1793189817985}
{"v": 2, "seq": 2, "kind": "interim", "role": "user", "text": "错", "_at_ms": 1793189818585}
{"v": 2, "seq": 3, "kind": "interim", "role": "user", "text": "我就是个", "_at_ms": 1793189819182}
{"v": 2, "seq": 4, "kind": "interim", "role": "user", "text": "笨蛋", "_at_ms": 1793189819779}
{"v": 2, "seq": 5, "kind": "interim", "role": "user", "text": "派大", "_at_ms": 1793189820394}
{"v": 2, "seq": 6, "kind": "interim", "role": "user", "text": "星我们", "_at_ms": 1793189820983}
{"v": 2, "seq": 7, "kind": "interim", "role": "user", "text": "一起去", "_at_ms": 1793189821581}
{"v": 2, "seq": 8, "kind": "interim", "role": "user", "text": "抓水母", "_at_ms": 1793189822183}
{"v": 2, "seq": 9, "kind": "interim", "role": "user", "text": "吧我", "_at_ms": 1793189822781}
{"v": 2, "seq": 10, "kind": "interim", "role": "user", "text": "们一起度", "_at_ms": 1793189823386}
{"v": 2, "seq": 11, "kind": "interim", "role": "user", "text": "过快乐的", "_at_ms": 1793189823992}
{"v": 2, "seq": 12, "kind": "interim", "role": "user", "text": "一天", "_at_ms": 1793189824583}
{"v": 2, "seq": 13, "kind": "user_final", "role": "user", "text": "没错,我就是个笨蛋派大星,我们一起去抓水母吧,我们一起度过快乐的一天", "_at_ms": 1793189826254}
{"v": 2, "seq": 14, "kind": "turn_start", "role": "assistant", "text": "", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189826284}
{"v": 2, "seq": 15, "kind": "assistant_interim", "role": "assistant", "text": "哈哈", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828238}
{"v": 2, "seq": 16, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828281}
{"v": 2, "seq": 17, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828282}
{"v": 2, "seq": 18, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828321}
{"v": 2, "seq": 19, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828365}
{"v": 2, "seq": 20, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828368}
{"v": 2, "seq": 21, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828406}
{"v": 2, "seq": 22, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828447}
{"v": 2, "seq": 23, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828448}
{"v": 2, "seq": 24, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828490}
{"v": 2, "seq": 25, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828532}
{"v": 2, "seq": 26, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828576}
{"v": 2, "seq": 27, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828576}
{"v": 2, "seq": 28, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828616}
{"v": 2, "seq": 29, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828658}
{"v": 2, "seq": 30, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828700}
{"v": 2, "seq": 31, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828701}
{"v": 2, "seq": 32, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828742}
{"v": 2, "seq": 33, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828744}
{"v": 2, "seq": 34, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828784}
{"v": 2, "seq": 35, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828785}
{"v": 2, "seq": 36, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828826}
{"v": 2, "seq": 37, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828867}
{"v": 2, "seq": 38, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828868}
{"v": 2, "seq": 39, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828910}
{"v": 2, "seq": 40, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828911}
{"v": 2, "seq": 41, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828954}
{"v": 2, "seq": 42, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189828996}
{"v": 2, "seq": 43, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829038}
{"v": 2, "seq": 44, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829081}
{"v": 2, "seq": 45, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829083}
{"v": 2, "seq": 46, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829122}
{"v": 2, "seq": 47, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829125}
{"v": 2, "seq": 48, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩上", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829165}
{"v": 2, "seq": 49, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩上,", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829166}
{"v": 2, "seq": 50, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩上,把", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829208}
{"v": 2, "seq": 51, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩上,把今天", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829209}
{"v": 2, "seq": 52, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩上,把今天当成", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829250}
{"v": 2, "seq": 53, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩上,把今天当成一个", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829292}
{"v": 2, "seq": 54, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩上,把今天当成一个不会", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829294}
{"v": 2, "seq": 55, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩上,把今天当成一个不会生锈", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829335}
{"v": 2, "seq": 56, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩上,把今天当成一个不会生锈的小", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829378}
{"v": 2, "seq": 57, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩上,把今天当成一个不会生锈的小罐头", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829419}
{"v": 2, "seq": 58, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩上,把今天当成一个不会生锈的小罐头,", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829461}
{"v": 2, "seq": 59, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩上,把今天当成一个不会生锈的小罐头,慢慢", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829463}
{"v": 2, "seq": 60, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩上,把今天当成一个不会生锈的小罐头,慢慢吃", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829504}
{"v": 2, "seq": 61, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩上,把今天当成一个不会生锈的小罐头,慢慢吃。", "speech_id": "speech_f0b3160be81e", "_at_ms": 1793189829548}
{"v": 2, "seq": 62, "kind": "assistant_final", "role": "assistant", "text": "哈哈,那走吧,派大星。今天水母网我背,你负责举着泡泡喊“出发”。\n\n抓完水母我们就坐在海滩上,把今天当成一个不会生锈的小罐头,慢慢吃。", "speech_id": "speech_f0b3160be81e", "turn_id": "d41a6e55-6be2-4f86-9414-18c9aa51c403", "_at_ms": 1793189847704}
{"v": 2, "seq": 63, "kind": "turn_end", "role": "assistant", "text": "", "speech_id": "speech_f0b3160be81e", "turn_id": "d41a6e55-6be2-4f86-9414-18c9aa51c403", "_at_ms": 1793189847705}
{"v": 2, "seq": 64, "kind": "interim", "role": "user", "text": "天雷滚", "_at_ms": 1793189848888}
{"v": 2, "seq": 65, "kind": "interim", "role": "user", "text": "滚我好", "_at_ms": 1793189849483}
{"v": 2, "seq": 66, "kind": "interim", "role": "user", "text": "怕", "_at_ms": 1793189850077}
{"v": 2, "seq": 67, "kind": "interim", "role": "user", "text": "怕劈", "_at_ms": 1793189850680}
{"v": 2, "seq": 68, "kind": "interim", "role": "user", "text": "的我浑", "_at_ms": 1793189851283}
{"v": 2, "seq": 69, "kind": "interim", "role": "user", "text": "身掉渣", "_at_ms": 1793189851881}
{"v": 2, "seq": 70, "kind": "interim", "role": "user", "text": "渣突", "_at_ms": 1793189852484}
{"v": 2, "seq": 71, "kind": "interim", "role": "user", "text": "破天", "_at_ms": 1793189853086}
{"v": 2, "seq": 72, "kind": "interim", "role": "user", "text": "劫我笑", "_at_ms": 1793189853693}
{"v": 2, "seq": 73, "kind": "interim", "role": "user", "text": "哈", "_at_ms": 1793189854298}
{"v": 2, "seq": 74, "kind": "interim", "role": "user", "text": "哈逆", "_at_ms": 1793189854881}
{"v": 2, "seq": 75, "kind": "interim", "role": "user", "text": "天改命", "_at_ms": 1793189855486}
{"v": 2, "seq": 76, "kind": "interim", "role": "user", "text": "我吹喇", "_at_ms": 1793189856080}
{"v": 2, "seq": 77, "kind": "interim", "role": "user", "text": "叭滴", "_at_ms": 1793189856684}
{"v": 2, "seq": 78, "kind": "interim", "role": "user", "text": "答滴答滴", "_at_ms": 1793189857291}
{"v": 2, "seq": 79, "kind": "interim", "role": "user", "text": "滴答", "_at_ms": 1793189857887}
{"v": 2, "seq": 80, "kind": "user_final", "role": "user", "text": "天雷滚滚,我好怕怕劈的我浑身掉渣渣,突破天劫,我笑哈哈逆天改命,我吹喇叭滴答滴答,滴滴答", "_at_ms": 1793189859574}
{"v": 2, "seq": 81, "kind": "turn_start", "role": "assistant", "text": "", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189859587}
{"v": 2, "seq": 82, "kind": "assistant_interim", "role": "assistant", "text": "那我", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189860878}
{"v": 2, "seq": 83, "kind": "assistant_interim", "role": "assistant", "text": "那我吹", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189860880}
{"v": 2, "seq": 84, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189860917}
{"v": 2, "seq": 85, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189860959}
{"v": 2, "seq": 86, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189860961}
{"v": 2, "seq": 87, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861001}
{"v": 2, "seq": 88, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861008}
{"v": 2, "seq": 89, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861045}
{"v": 2, "seq": 90, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861087}
{"v": 2, "seq": 91, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861130}
{"v": 2, "seq": 92, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。\n\n", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861130}
{"v": 2, "seq": 93, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。\n\n雷", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861173}
{"v": 2, "seq": 94, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。\n\n雷声", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861175}
{"v": 2, "seq": 95, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。\n\n雷声当", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861216}
{"v": 2, "seq": 96, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。\n\n雷声当鼓", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861258}
{"v": 2, "seq": 97, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。\n\n雷声当鼓点", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861301}
{"v": 2, "seq": 98, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。\n\n雷声当鼓点,", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861302}
{"v": 2, "seq": 99, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。\n\n雷声当鼓点,掉", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861344}
{"v": 2, "seq": 100, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。\n\n雷声当鼓点,掉渣", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861387}
{"v": 2, "seq": 101, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。\n\n雷声当鼓点,掉渣渣", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861388}
{"v": 2, "seq": 102, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。\n\n雷声当鼓点,掉渣渣就当", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861430}
{"v": 2, "seq": 103, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。\n\n雷声当鼓点,掉渣渣就当礼", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861432}
{"v": 2, "seq": 104, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。\n\n雷声当鼓点,掉渣渣就当礼花", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861471}
{"v": 2, "seq": 105, "kind": "assistant_interim", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。\n\n雷声当鼓点,掉渣渣就当礼花。", "speech_id": "speech_9ae41249c69d", "_at_ms": 1793189861472}
{"v": 2, "seq": 106, "kind": "assistant_final", "role": "assistant", "text": "那我吹小号,滴滴答,给你伴奏。\n\n雷声当鼓点,掉渣渣就当礼花。", "speech_id": "speech_9ae41249c69d", "turn_id": "43a68fc7-7e9c-4ae0-a6c7-7cf09bccd620", "_at_ms": 1793189872924}
{"v": 2, "seq": 107, "kind": "turn_end", "role": "assistant", "text": "", "speech_id": "speech_9ae41249c69d", "turn_id": "43a68fc7-7e9c-4ae0-a6c7-7cf09bccd620", "_at_ms": 1793189872926}
{"v": 2, "seq": 108, "kind": "interim", "role": "user", "text": "你是不是", "_at_ms": 1793189874341}
{"v": 2, "seq": 109, "kind": "interim", "role": "user", "text": "早就", "_at_ms": 1793189874934}
{"v": 2, "seq": 110, "kind": "interim", "role": "user", "text": "想睡我", "_at_ms": 1793189875540}
{"v": 2, "seq": 111, "kind": "interim", "role": "user", "text": "了", "_at_ms": 1793189876138}
{"v": 2, "seq": 112, "kind": "user_final", "role": "user", "text": "你是不是早就想睡我了呀", "_at_ms": 1793189877129}
{"v": 2, "seq": 113, "kind": "turn_start", "role": "assistant", "text": "", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189877136}
{"v": 2, "seq": 114, "kind": "assistant_interim", "role": "assistant", "text": "哈哈", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880190}
{"v": 2, "seq": 115, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880193}
{"v": 2, "seq": 116, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880232}
{"v": 2, "seq": 117, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880234}
{"v": 2, "seq": 118, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880273}
{"v": 2, "seq": 119, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880275}
{"v": 2, "seq": 120, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880315}
{"v": 2, "seq": 121, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880318}
{"v": 2, "seq": 122, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880357}
{"v": 2, "seq": 123, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880400}
{"v": 2, "seq": 124, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880402}
{"v": 2, "seq": 125, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880442}
{"v": 2, "seq": 126, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880484}
{"v": 2, "seq": 127, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880485}
{"v": 2, "seq": 128, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880527}
{"v": 2, "seq": 129, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880531}
{"v": 2, "seq": 130, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880567}
{"v": 2, "seq": 131, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880568}
{"v": 2, "seq": 132, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880610}
{"v": 2, "seq": 133, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880611}
{"v": 2, "seq": 134, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880652}
{"v": 2, "seq": 135, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880694}
{"v": 2, "seq": 136, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880735}
{"v": 2, "seq": 137, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880777}
{"v": 2, "seq": 138, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880778}
{"v": 2, "seq": 139, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880820}
{"v": 2, "seq": 140, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880862}
{"v": 2, "seq": 141, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880903}
{"v": 2, "seq": 142, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880946}
{"v": 2, "seq": 143, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880946}
{"v": 2, "seq": 144, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189880988}
{"v": 2, "seq": 145, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881032}
{"v": 2, "seq": 146, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881074}
{"v": 2, "seq": 147, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881117}
{"v": 2, "seq": 148, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881117}
{"v": 2, "seq": 149, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881159}
{"v": 2, "seq": 150, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881160}
{"v": 2, "seq": 151, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881202}
{"v": 2, "seq": 152, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881203}
{"v": 2, "seq": 153, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881244}
{"v": 2, "seq": 154, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881245}
{"v": 2, "seq": 155, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881287}
{"v": 2, "seq": 156, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881288}
{"v": 2, "seq": 157, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881330}
{"v": 2, "seq": 158, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881374}
{"v": 2, "seq": 159, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881415}
{"v": 2, "seq": 160, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881458}
{"v": 2, "seq": 161, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881500}
{"v": 2, "seq": 162, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881501}
{"v": 2, "seq": 163, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881542}
{"v": 2, "seq": 164, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881542}
{"v": 2, "seq": 165, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881584}
{"v": 2, "seq": 166, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881627}
{"v": 2, "seq": 167, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881627}
{"v": 2, "seq": 168, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881670}
{"v": 2, "seq": 169, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881670}
{"v": 2, "seq": 170, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881712}
{"v": 2, "seq": 171, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881713}
{"v": 2, "seq": 172, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881755}
{"v": 2, "seq": 173, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881796}
{"v": 2, "seq": 174, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静地", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881838}
{"v": 2, "seq": 175, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静地聊", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881838}
{"v": 2, "seq": 176, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静地聊很久", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881880}
{"v": 2, "seq": 177, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静地聊很久,", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881923}
{"v": 2, "seq": 178, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静地聊很久,然后", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881925}
{"v": 2, "seq": 179, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静地聊很久,然后看", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189881964}
{"v": 2, "seq": 180, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静地聊很久,然后看你的", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189882006}
{"v": 2, "seq": 181, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静地聊很久,然后看你的消息", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189882007}
{"v": 2, "seq": 182, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静地聊很久,然后看你的消息慢慢", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189882048}
{"v": 2, "seq": 183, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静地聊很久,然后看你的消息慢慢变成", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189882049}
{"v": 2, "seq": 184, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静地聊很久,然后看你的消息慢慢变成一句", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189882091}
{"v": 2, "seq": 185, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静地聊很久,然后看你的消息慢慢变成一句“", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189882091}
{"v": 2, "seq": 186, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静地聊很久,然后看你的消息慢慢变成一句“晚安", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189882133}
{"v": 2, "seq": 187, "kind": "assistant_interim", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静地聊很久,然后看你的消息慢慢变成一句“晚安”。", "speech_id": "speech_36bea918d22a", "_at_ms": 1793189882134}
{"v": 2, "seq": 188, "kind": "assistant_final", "role": "assistant", "text": "哈哈,你是想让我回答得浪漫点,还是诚实点?\n\n如果是浪漫版:我想和你并肩躺着,听雨数星星,然后各自做各自的梦。\n\n如果是诚实版:我这边只有文字能穿过两个世界,所以最接近“睡”的动作,大概就是陪你安静地聊很久,然后看你的消息慢慢变成一句“晚安”。", "speech_id": "speech_36bea918d22a", "turn_id": "406dba7e-e826-48f4-ad9c-ea0330b506c4", "_at_ms": 1793189905432}
{"v": 2, "seq": 189, "kind": "turn_end", "role": "assistant", "text": "", "speech_id": "speech_36bea918d22a", "turn_id": "406dba7e-e826-48f4-ad9c-ea0330b506c4", "_at_ms": 1793189905433}
Binary file not shown.
File diff suppressed because one or more lines are too long
+90
View File
@@ -0,0 +1,90 @@
{
"round": {
"play_label": "bajie",
"reply": {
"kind": "turn_end",
"speech_id": "speech_322d5cae3e49",
"reason": null
}
},
"session_voice": "cg-f2ec321d",
"midcall_selection_status": 200,
"midcall_selection_body": {
"voice": "rain",
"label": "rain",
"updated_at": 1793190128276
},
"worker_state_midcall": {
"exists": true,
"content": {
"voice": "cg-f2ec321d"
}
},
"worker_state_after_hangup": {
"exists": true,
"content": {
"voice": "cg-f2ec321d"
}
},
"hangup": {
"delete_status": 200,
"delete_body": {
"ended": true,
"room": "cg-voice-h9ncn972c6"
},
"delete_ms": 1793190128281,
"agent_frames_after_delete": 2,
"room_removed": true
},
"call": {
"tag": "call2",
"session": {
"url": "wss://192.168.200.12:8363",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2aWRlbyI6eyJyb29tSm9pbiI6dHJ1ZSwicm9vbSI6ImNnLXZvaWNlLWg5bmNuOTcyYzYiLCJjYW5QdWJsaXNoIjp0cnVlLCJjYW5TdWJzY3JpYmUiOnRydWUsImNhblB1Ymxpc2hEYXRhIjp0cnVlfSwic3ViIjoidXNlci1jdGR0Y3N5diIsImlzcyI6ImRldmtleSIsIm5iZiI6MTc5MzE5MDA4OCwiZXhwIjoxNzkzMTkwMzg4LCJuYW1lIjoi55So5oi3In0.bxc8SOSq1b2RHCEOHAJL-e7sXVXy0hIHcNLPDqSydiw",
"room": "cg-voice-h9ncn972c6",
"session_id": "FnM8-yTH5keAHRRJiS-EJBwp",
"agent_name": "cybergril-voice-agent",
"epoch": 1,
"expires_at": 1793190988340,
"voice": "cg-f2ec321d"
},
"session_voice": "cg-f2ec321d",
"subtitle_count": 83,
"seq_monotonic": true,
"agent_frames": 3930,
"agent_audio_seconds": 39.3,
"agent_audio_rate": 48000,
"agent_joined_ms": 1793190088945,
"agent_left_ms": null,
"subtitles_file": "/opt/cybergril-hel907/evidence/call2.subtitles.jsonl",
"frames_file": "/opt/cybergril-hel907/evidence/call2.frames.json",
"agent_audio_file": "/opt/cybergril-hel907/evidence/call2.agent.wav"
},
"budget_after": {
"at_ms": 1793190132314,
"token_usage": [
{
"day": "2026-10-28",
"scene": "dialogue_main",
"used": 17363
}
],
"request_usage": [
{
"day": "2026-10-28",
"category": "dialogue",
"requests": 6
}
],
"budget_total": [
{
"key": "total_requests",
"value": 6
},
{
"key": "total_tokens",
"value": 17363
}
]
}
}
@@ -0,0 +1,83 @@
{"v": 2, "seq": 1, "kind": "interim", "role": "user", "text": "师", "_at_ms": 1793190089662}
{"v": 2, "seq": 2, "kind": "interim", "role": "user", "text": "傅", "_at_ms": 1793190090262}
{"v": 2, "seq": 3, "kind": "interim", "role": "user", "text": "哎这", "_at_ms": 1793190090856}
{"v": 2, "seq": 4, "kind": "interim", "role": "user", "text": "取经", "_at_ms": 1793190091466}
{"v": 2, "seq": 5, "kind": "interim", "role": "user", "text": "路比", "_at_ms": 1793190092058}
{"v": 2, "seq": 6, "kind": "interim", "role": "user", "text": "高老", "_at_ms": 1793190092653}
{"v": 2, "seq": 7, "kind": "interim", "role": "user", "text": "庄种地", "_at_ms": 1793190093255}
{"v": 2, "seq": 8, "kind": "interim", "role": "user", "text": "还", "_at_ms": 1793190093863}
{"v": 2, "seq": 9, "kind": "interim", "role": "user", "text": "苦俺", "_at_ms": 1793190094459}
{"v": 2, "seq": 10, "kind": "interim", "role": "user", "text": "老中", "_at_ms": 1793190095057}
{"v": 2, "seq": 11, "kind": "interim", "role": "user", "text": "饿的能", "_at_ms": 1793190095665}
{"v": 2, "seq": 12, "kind": "interim", "role": "user", "text": "吞下", "_at_ms": 1793190096261}
{"v": 2, "seq": 13, "kind": "interim", "role": "user", "text": "石龙素", "_at_ms": 1793190096860}
{"v": 2, "seq": 14, "kind": "interim", "role": "user", "text": "包", "_at_ms": 1793190097445}
{"v": 2, "seq": 15, "kind": "interim", "role": "user", "text": "子", "_at_ms": 1793190098053}
{"v": 2, "seq": 16, "kind": "interim", "role": "user", "text": "猴哥", "_at_ms": 1793190098659}
{"v": 2, "seq": 17, "kind": "interim", "role": "user", "text": "你筋", "_at_ms": 1793190099259}
{"v": 2, "seq": 18, "kind": "interim", "role": "user", "text": "斗云", "_at_ms": 1793190099851}
{"v": 2, "seq": 19, "kind": "interim", "role": "user", "text": "快", "_at_ms": 1793190100449}
{"v": 2, "seq": 20, "kind": "interim", "role": "user", "text": "要不", "_at_ms": 1793190101056}
{"v": 2, "seq": 21, "kind": "interim", "role": "user", "text": "先", "_at_ms": 1793190101653}
{"v": 2, "seq": 22, "kind": "interim", "role": "user", "text": "去画个", "_at_ms": 1793190102253}
{"v": 2, "seq": 23, "kind": "user_final", "role": "user", "text": "师傅,哎,这取经路比高,老庄种地还苦,俺老猪饿的能吞下石龙素包子,猴哥,你筋斗云块,要不先去化个缘", "_at_ms": 1793190104591}
{"v": 2, "seq": 24, "kind": "turn_start", "role": "assistant", "text": "", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190108293}
{"v": 2, "seq": 25, "kind": "assistant_interim", "role": "assistant", "text": "八戒", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109566}
{"v": 2, "seq": 26, "kind": "assistant_interim", "role": "assistant", "text": "八戒,", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109572}
{"v": 2, "seq": 27, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109608}
{"v": 2, "seq": 28, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109649}
{"v": 2, "seq": 29, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109692}
{"v": 2, "seq": 30, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109693}
{"v": 2, "seq": 31, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109735}
{"v": 2, "seq": 32, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109777}
{"v": 2, "seq": 33, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109778}
{"v": 2, "seq": 34, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109819}
{"v": 2, "seq": 35, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109821}
{"v": 2, "seq": 36, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109862}
{"v": 2, "seq": 37, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109864}
{"v": 2, "seq": 38, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109905}
{"v": 2, "seq": 39, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109950}
{"v": 2, "seq": 40, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109951}
{"v": 2, "seq": 41, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190109989}
{"v": 2, "seq": 42, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110032}
{"v": 2, "seq": 43, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110033}
{"v": 2, "seq": 44, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110073}
{"v": 2, "seq": 45, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110074}
{"v": 2, "seq": 46, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110115}
{"v": 2, "seq": 47, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110157}
{"v": 2, "seq": 48, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110200}
{"v": 2, "seq": 49, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110202}
{"v": 2, "seq": 50, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110241}
{"v": 2, "seq": 51, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110243}
{"v": 2, "seq": 52, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110287}
{"v": 2, "seq": 53, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110288}
{"v": 2, "seq": 54, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110326}
{"v": 2, "seq": 55, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110328}
{"v": 2, "seq": 56, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110368}
{"v": 2, "seq": 57, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110411}
{"v": 2, "seq": 58, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110412}
{"v": 2, "seq": 59, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110453}
{"v": 2, "seq": 60, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110455}
{"v": 2, "seq": 61, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110494}
{"v": 2, "seq": 62, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110497}
{"v": 2, "seq": 63, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110537}
{"v": 2, "seq": 64, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110545}
{"v": 2, "seq": 65, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110578}
{"v": 2, "seq": 66, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110579}
{"v": 2, "seq": 67, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110620}
{"v": 2, "seq": 68, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面正好", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110662}
{"v": 2, "seq": 69, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面正好有个", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110704}
{"v": 2, "seq": 70, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面正好有个小", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110705}
{"v": 2, "seq": 71, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面正好有个小摊", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110746}
{"v": 2, "seq": 72, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面正好有个小摊,", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110788}
{"v": 2, "seq": 73, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面正好有个小摊,写着", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110830}
{"v": 2, "seq": 74, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面正好有个小摊,写着“", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110873}
{"v": 2, "seq": 75, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面正好有个小摊,写着“素", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110873}
{"v": 2, "seq": 76, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面正好有个小摊,写着“素包子", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110914}
{"v": 2, "seq": 77, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面正好有个小摊,写着“素包子,", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110957}
{"v": 2, "seq": 78, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面正好有个小摊,写着“素包子,两", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110957}
{"v": 2, "seq": 79, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面正好有个小摊,写着“素包子,两文", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190110998}
{"v": 2, "seq": 80, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面正好有个小摊,写着“素包子,两文钱", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190111042}
{"v": 2, "seq": 81, "kind": "assistant_interim", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面正好有个小摊,写着“素包子,两文钱”。", "speech_id": "speech_322d5cae3e49", "_at_ms": 1793190111042}
{"v": 2, "seq": 82, "kind": "assistant_final", "role": "assistant", "text": "八戒,你这嘴比那九齿钉耙还利索。\n\n我刚把筋斗云系在旁边那棵歪脖子树上,它说今天腿有点酸,不太想飞。\n\n你看,前面正好有个小摊,写着“素包子,两文钱”。", "speech_id": "speech_322d5cae3e49", "turn_id": "5cd59bcf-ffaa-4b48-9081-0478d6e35a01", "_at_ms": 1793190128165}
{"v": 2, "seq": 83, "kind": "turn_end", "role": "assistant", "text": "", "speech_id": "speech_322d5cae3e49", "turn_id": "5cd59bcf-ffaa-4b48-9081-0478d6e35a01", "_at_ms": 1793190128168}
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More