mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
fix(dictation): invalidate run before delayed teardown, remove unwrap
Address two review comments: 1. (useRealtimeDictation.ts) Increment activeRunIdRef immediately in the manual-commit cleanup path so late transcript events from the 3s grace window are rejected by handleRealtimeEvent. Previously, the run stayed valid during the timeout, allowing transcripts to write back into the composer after a send, edit-save, or navigation. 2. (transcribe.rs) Replace as_object_mut().unwrap() with a branch that builds the correct JSON literal directly. Avoids introducing an unwrap in a production path per AGENTS.md rules.
This commit is contained in:
@@ -189,18 +189,18 @@ async fn can_mint_session(
|
||||
fn build_session_payload(model: &str) -> Value {
|
||||
let uses_manual_commit = model.contains("realtime-whisper");
|
||||
|
||||
let mut audio_input = serde_json::json!({
|
||||
"transcription": {
|
||||
"model": model,
|
||||
}
|
||||
});
|
||||
|
||||
if !uses_manual_commit {
|
||||
audio_input.as_object_mut().unwrap().insert(
|
||||
"turn_detection".to_string(),
|
||||
serde_json::json!({ "type": "server_vad" }),
|
||||
);
|
||||
}
|
||||
let audio_input = if uses_manual_commit {
|
||||
// Manual commit mode — omit turn_detection entirely.
|
||||
serde_json::json!({
|
||||
"transcription": { "model": model }
|
||||
})
|
||||
} else {
|
||||
// Server VAD mode — include turn_detection.
|
||||
serde_json::json!({
|
||||
"transcription": { "model": model },
|
||||
"turn_detection": { "type": "server_vad" }
|
||||
})
|
||||
};
|
||||
|
||||
serde_json::json!({
|
||||
"session": {
|
||||
|
||||
@@ -102,6 +102,11 @@ export function useRealtimeDictation({
|
||||
|
||||
if (needsCommit && dc) {
|
||||
commitAudioBuffer(dc);
|
||||
// Mark the run stale immediately so late transcript events from the
|
||||
// data channel are rejected by handleRealtimeEvent. This prevents
|
||||
// transcripts from writing back into the composer after a send,
|
||||
// edit-save, or navigation that triggered this cleanup.
|
||||
activeRunIdRef.current += 1;
|
||||
// Stop the mic immediately so no new audio is sent after commit.
|
||||
for (const track of streamRef.current?.getTracks() ?? []) {
|
||||
track.stop();
|
||||
@@ -109,16 +114,12 @@ export function useRealtimeDictation({
|
||||
streamRef.current = null;
|
||||
audioCaptureRef.current?.close();
|
||||
audioCaptureRef.current = null;
|
||||
// Delay full teardown to allow the final transcript to arrive.
|
||||
// Delay WebRTC teardown briefly for clean protocol shutdown (the
|
||||
// commit message needs to reach OpenAI before the channel closes).
|
||||
const pc = peerConnectionRef.current;
|
||||
peerConnectionRef.current = null;
|
||||
dataChannelRef.current = null;
|
||||
const runId = activeRunIdRef.current;
|
||||
setTimeout(() => {
|
||||
// Only tear down if no new run started in the meantime.
|
||||
if (activeRunIdRef.current === runId) {
|
||||
activeRunIdRef.current += 1;
|
||||
}
|
||||
dc.close();
|
||||
pc?.close();
|
||||
}, 3000);
|
||||
|
||||
Reference in New Issue
Block a user