Skip to content

feat(#613): retain recording on ASR failure + retranscribe from history#640

Closed
H-Chris233 wants to merge 1 commit into
Open-Less:betafrom
H-Chris233:feat/issue-613-retranscribe-on-failure
Closed

feat(#613): retain recording on ASR failure + retranscribe from history#640
H-Chris233 wants to merge 1 commit into
Open-Less:betafrom
H-Chris233:feat/issue-613-retranscribe-on-failure

Conversation

@H-Chris233

@H-Chris233 H-Chris233 commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

User description

Closes #613

改动

后端 (Rust)

  • 设置 autoRetainRecordingOnFailure(默认 false)控制失败时 WAV 保留
  • 14 个 ASR 失败分支写入 history 失败条目
  • retranscribe_history_entry IPC:读 WAV -> 解码 PCM -> 调当前 ASR -> 更新 history
  • 支持 Whisper / MiMo;Volcengine/Bailian/本地模型返回明确错误(后续迭代)
  • HistoryStore::find_entry / update_entry
  • 修 emptyTranscript session id 与 WAV 文件名不对齐 bug

前端

  • 历史页失败条目显示「重新转录」按钮
  • Settings 新增开关
  • 5 语言 i18n

决策

# 决策 结果
1 录音保留策略 autoRetainRecordingOnFailure 独立开关,默认 false
2 重转录 ASR 始终用当前 active_asr_provider
3 成功后处理 更新 rawTranscript + 清除 errorCode(polish 后续迭代)
4 历史 ID 复用 current_session_id 对齐 WAV
5 错误码 transcribeFailed / transcribeTimeout
6 次数限制 不限

PR Type

Bug fix, Enhancement


Description

  • Retain recording on ASR failure via new switch

  • Write failed transcription to history with errorCode

  • Support retranscribe from history page

  • Fix empty transcript session id alignment with WAV file


Diagram Walkthrough

flowchart LR
    A["Recording ends"] --> B{ASR success?}
    B -- "Yes" --> C["Normal history entry"]
    B -- "No" --> D["Auto retain audio?"]
    D -- "Yes" --> E["History entry with errorCode"]
    D -- "No" --> F["No history entry"]
    E --> G["User clicks Retranscribe"]
    G --> H["IPC: decode WAV & re-transcribe"]
    H --> I{Success?}
    I -- "Yes" --> J["Update entry, clear error"]
    I -- "No" --> K["Show error, entry unchanged"]
Loading

File Walkthrough

Relevant files
Enhancement
12 files
mimo.rs
Add transcribe_pcm method for retranscription                       
+5/-0     
wav.rs
Implement WAV to PCM decoder for retranscribe                       
+58/-0   
whisper.rs
Add transcribe_pcm method for retranscription                       
+5/-0     
history.rs
Add retranscribe_history_entry IPC command                             
+97/-0   
coordinator.rs
Re-export credential readers for retranscribe command       
+2/-0     
dictation_end.rs
Append failure history entries on ASR errors                         
+108/-1 
dictation_session.rs
Extend audio archive condition for failure retention         
+8/-5     
persistence.rs
Add find_entry and update_entry to HistoryStore                   
+27/-0   
ipc.ts
Add retranscribeHistoryEntry IPC function                               
+28/-0   
types.ts
Add autoRetainRecordingOnFailure to UserPreferences           
+2/-0     
History.tsx
Add retranscribe button and handler in history page           
+23/-1   
DataStorageSection.tsx
Add autoRetainRecordingOnFailure switch in settings           
+7/-0     
Configuration changes
2 files
lib.rs
Register retranscribe_history_entry command                           
+1/-0     
types.rs
Add auto_retain_recording_on_failure preference field       
+10/-0   
I18n
5 files
en.ts
Add retranscribe and failure retention i18n keys                 
+5/-0     
ja.ts
Add retranscribe and failure retention i18n keys                 
+5/-0     
ko.ts
Add retranscribe and failure retention i18n keys                 
+5/-0     
zh-CN.ts
Add retranscribe and failure retention i18n keys                 
+5/-0     
zh-TW.ts
Add retranscribe and failure retention i18n keys                 
+5/-0     

…rom history

- 新增 autoRetainRecordingOnFailure 设置(默认 false)
- 14 个 ASR 失败分支写入 history(errorCode: transcribeFailed/transcribeTimeout)
- 新增 retranscribe_history_entry IPC(支持 Whisper/MiMo WAV PCM 转写)
- 历史页渲染「重新转录」按钮 + 交互状态
- Settings 页面新增「转录失败时保留录音」开关
- 修 emptyTranscript 路径 session id 对齐 WAV 文件 bug
- 5 语言(zh-CN/en/zh-TW/ja/ko)i18n 补全

Closes Open-Less#613
@github-actions

Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

613 - Partially compliant

Compliant requirements:

  • 历史条目在详情区可播放/导出原始录音(复用现有 readAudioRecording 能力)
  • 历史详情提供「重新转录」按钮:对归档 wav 重新调用当前配置的 ASR 提供商
  • 重新转录失败时给出明确错误提示,保留原录音不丢失

Non-compliant requirements:

  • ASR 转录失败时,若录音已成功归档,应写入一条历史记录(建议 errorCode 区分失败类型,如 transcribeFailed)— 当前代码无条件写入历史条目,未检查录音是否成功归档;不满足「若录音已成功归档」的前提条件。
  • 重新转录成功后更新该条历史的 rawTranscript / finalText(及后续润色流程),并清除或更新错误状态 — 只更新了 rawTranscript,未更新 finalText,也未触发后续润色流程。

Requires further human verification:

(empty)

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Unconditional history write may contradict ticket spec

The append_failed_history_entry function is called in every ASR failure branch regardless of whether the recording was actually archived (i.e., auto_retain_recording_on_failure or record_audio_for_debug is enabled). The ticket requirement states that a history entry should only be written "若录音已成功归档" (if the recording was successfully archived). The current behavior writes a history entry even when the recording was not saved, which clutters the history with entries that have has_audio_recording: false and cannot be retranscribed. This may confuse users who expect history to contain only sessions with retained audio. While the PR decision record indicates an independent switch, the unconditional write appears to be a deviation from the issue's acceptance criteria and should be reconsidered or justified.

/// #613: ASR 转录失败时向 history 写入一条失败条目,保留录音供用户在历史页中重试。
/// 复用录音时的 session_id 以保证 WAV 文件名对齐;用两类 error_code 区分超时/引擎失败。
fn append_failed_history_entry(
    inner: &Arc<Inner>,
    session_id: Uuid,
    elapsed_ms: u64,
    error_code: &str,
) {
    let session = DictationSession {
        id: session_id.to_string(),
        created_at: chrono::Utc::now().to_rfc3339(),
        raw_transcript: String::new(),
        final_text: String::new(),
        mode: inner.prefs.get().default_mode,
        style_pack_id: None,
        translation_active: false,
        polish_source: None,
        app_bundle_id: None,
        app_name: None,
        insert_status: InsertStatus::Failed,
        error_code: Some(error_code.to_string()),
        duration_ms: Some(elapsed_ms),
        dictionary_entry_count: None,
        has_audio_recording: Some(inner.audio_archive_active.load(Ordering::Relaxed)),
    };
    let prefs_snapshot = inner.prefs.get();
    if let Err(e) = inner.history.append_with_retention(
        session,
        prefs_snapshot.history_retention_days,
        prefs_snapshot.history_max_entries,
    ) {
        log::error!("[coord] history append on ASR failure failed: {e}");
    }
}

@H-Chris233 H-Chris233 closed this Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[asr] 转录失败时保留录音并支持在历史中重新转录

1 participant