背景
#655 已于 2026-06-21 关闭(评论「已完成」),但落地的是 「安全版排队接力」(commit 6536160,含于 v1.3.11-tauri),并非 #655 原文描述的完整并发架构。
已交付(#655 子集,勿重复实现)
| 能力 |
实现位置 |
Toggle:识别/润色期间按键 → 缓存在 hotkey channel → 上一条 Idle 后 ~0ms 接力开录 |
dictation.rs:HOTKEY_QUEUE_GRACE_MS + is_queued_chain_press |
与 #545 冷却区分:120ms grace vs 600ms POST_SESSION_COOLDOWN_MS |
同上 + 单元测试 queued_chain_press_allowed_within_grace_blocked_after |
| ASR 失败保留音频 + 静默重试 + 历史手动重转录 |
同 commit(偏 #613) |
仍未实现(本 issue 范围)
#655 原文 P0 / 接受标准中,排队接力未覆盖的部分:
- 真并发录音:session A 处于
Processing / Inserting 时,session B 可立即进入 Listening 并采集 PCM(麦克风互斥仅约束「同时 Listening」)。
- 注入 FIFO:按录音结束顺序串行 insert;被取消 session 不占队列 slot;各 session 使用
begin_session 时的 focus_target 快照。
- 状态机拆分:录音生命周期与 ASR/润色/插入 pipeline 解耦(非全局单一
SessionPhase 阻塞 begin_session)。
- 热键语义:
Processing / Inserting 时 Toggle/Hold 有明确定义(非 _ => {});Hold 在 processing 期间的行为需定义。
- (可选 P1) 胶囊/UI 能表达「A 润色 + B 录音」等多 job 状态。
现状(与 #655 相同根因,2026-06 代码快照)
begin_session_state 仍仅在 Idle 时允许进入 Starting。handle_pressed 对 Processing / Inserting 仍为 _ => {}——排队接力依赖 channel 缓冲 + 收尾后 Idle 分支,不能在 Processing 期间直接 begin_session。
资源仍为单槽:Inner.state、asr、recorder 各至多一份;无 insert_queue worker。
建议架构(摘自 #655,供实现参考)
┌─────────────────┐ end_recording ┌──────────────────────┐
│ Recording FSM │ ─────────────────────► │ Pipeline queue │
│ (Listening 单例)│ │ per-session jobs: │
└─────────────────┘ │ ASR → polish → enqueue│
▲ └──────────┬───────────┘
│ begin 立即允许(Idle 或 │
│ 「仅 Listening 占用 mic」) ▼
│ ┌──────────────────────┐
└──────────────────────────────────│ Insert FIFO worker │
│ (TextInserter 串行) │
└──────────────────────┘
可能涉及的模块(与 #655 一致):
| 模块 |
变更方向 |
coordinator_state.rs |
拆分录音 phase 与 pipeline job;或 per-session struct + 全局 recording slot |
coordinator/dictation.rs |
end_session 拆为 stop_recording + spawn pipeline;热键 gating 改判 |
coordinator/resources.rs |
recorder/ASR 生命周期与 pipeline 分离 |
新 insert_queue.rs(或类似) |
VecDeque<InsertJob> + 单 worker |
coordinator.rs emit_capsule |
多 job UI(P1) |
dictation_session.rs / dictation_end.rs |
Android/Remote 路径同步(若本期包含) |
与排队接力的关系:6536160 的 queue-chain 可在完整方案落地后保留或替换——若真并发已实现,grace 窗口逻辑可能仅用于 #545 误触防护,需一并评估。
接受标准(Checklist)
非目标
- 不要求 ASR provider 多连接并行(可接受「录音并发 + 转写串行 + 注入串行」)。
- 不改变
Inserting 阶段 cancel 拒绝策略。
- QA / Voice Agent 与主听写互斥不变(除非单独 issue)。
相关
背景
#655 已于 2026-06-21 关闭(评论「已完成」),但落地的是 「安全版排队接力」(commit
6536160,含于 v1.3.11-tauri),并非 #655 原文描述的完整并发架构。已交付(#655 子集,勿重复实现)
Idle后 ~0ms 接力开录dictation.rs:HOTKEY_QUEUE_GRACE_MS+is_queued_chain_pressPOST_SESSION_COOLDOWN_MSqueued_chain_press_allowed_within_grace_blocked_after仍未实现(本 issue 范围)
#655 原文 P0 / 接受标准中,排队接力未覆盖的部分:
Processing/Inserting时,session B 可立即进入Listening并采集 PCM(麦克风互斥仅约束「同时 Listening」)。begin_session时的focus_target快照。SessionPhase阻塞begin_session)。Processing/Inserting时 Toggle/Hold 有明确定义(非_ => {});Hold 在 processing 期间的行为需定义。现状(与 #655 相同根因,2026-06 代码快照)
begin_session_state仍仅在Idle时允许进入Starting。handle_pressed对Processing/Inserting仍为_ => {}——排队接力依赖 channel 缓冲 + 收尾后Idle分支,不能在 Processing 期间直接begin_session。资源仍为单槽:
Inner.state、asr、recorder各至多一份;无insert_queueworker。建议架构(摘自 #655,供实现参考)
可能涉及的模块(与 #655 一致):
coordinator_state.rscoordinator/dictation.rsend_session拆为 stop_recording + spawn pipeline;热键 gating 改判coordinator/resources.rsinsert_queue.rs(或类似)VecDeque<InsertJob>+ 单 workercoordinator.rsemit_capsuledictation_session.rs/dictation_end.rs与排队接力的关系:
6536160的 queue-chain 可在完整方案落地后保留或替换——若真并发已实现,grace 窗口逻辑可能仅用于 #545 误触防护,需一并评估。接受标准(Checklist)
Processing后,用户可立即开始录音 B(Listening),B 正常采集 PCM。Processing中再次 Toggle 能开始 B 或停止当前Listening(行为文档化)。POST_SESSION_COOLDOWN_MS不阻止「Processing 期间的新录音」(与 [ui] 听写快速连按应在上一轮完全结束前忽略激活(动画已缓解,逻辑未改) #545 / [area:ux] 取消录音后胶囊延迟关闭,应立刻消失 #654 协调)。session_id、history;has_audio_recording/ wav 归档语义不变([asr] 转录失败时保留录音并支持在历史中重新转录 #613)。Inserting仍不可 cancel;流式already_streamed语义不变。非目标
Inserting阶段 cancel 拒绝策略。相关
POST_SESSION_COOLDOWN_MS6536160(v1.3.11)