fix: address review comments — nested audio schema, item separators, safe auto-submit clear

- Relay: restructure OpenAI client-secrets payload to use the current
  typed transcription schema (audio.input.transcription) instead of the
  deprecated top-level input_audio_transcription field.
- realtimeAudio: insert space separators between transcript items when
  neither the preceding nor following text has whitespace, preventing
  multi-utterance runs from merging into unreadable text.
- useDictation: remove premature setText('') after auto-submit — the
  send flow handles clearing on success, so dictated text survives if a
  mention dialog opens or the send is blocked.

Signed-off-by: klopez4212 <klopez4212@gmail.com>
This commit is contained in:
klopez4212
2026-07-11 16:18:07 +01:00
parent cd669cbf3e
commit 586d0de244
3 changed files with 22 additions and 16 deletions
+9 -7
View File
@@ -81,14 +81,16 @@ pub async fn create_transcribe_session(
.header("Authorization", format!("Bearer {api_key}"))
.header("Content-Type", "application/json")
.json(&serde_json::json!({
"session": {
"type": "transcription",
"input_audio_transcription": {
"model": model,
},
"turn_detection": {
"type": "server_vad",
"type": "transcription",
"audio": {
"input": {
"transcription": {
"model": model,
}
}
},
"turn_detection": {
"type": "server_vad",
}
}))
.timeout(std::time::Duration::from_secs(10))
@@ -63,8 +63,13 @@ export function useDictation({
return;
}
// Set the text first so the composer shows the final dictated content,
// then trigger send. We intentionally do NOT clear the composer here —
// the send flow in MessageComposer handles clearing on successful send.
// If a mention dialog opens (non-member mention), the text stays in the
// composer so the user doesn't lose their dictated message.
setText(textWithoutPhrase.trim());
onSend(textWithoutPhrase.trim());
setText("");
lastTranscriptRef.current = "";
},
[autoSubmitPhrases, getText, onSend, isSendBlockedRef, setText],
@@ -89,7 +89,12 @@ export function getTranscriptText(state: TranscriptSegmentState): string {
for (const id of state.itemOrder) {
const seg = state.items.get(id);
if (!seg) continue;
result += seg.finalized ?? seg.pending;
const text = seg.finalized ?? seg.pending;
if (!text) continue;
if (result && !result.endsWith(" ") && !text.startsWith(" ")) {
result += " ";
}
result += text;
}
return result;
}
@@ -136,13 +141,7 @@ export function mergeTranscriptEvent(
}
// Reconstruct full text from all items in order.
let result = "";
for (const id of state.itemOrder) {
const seg = state.items.get(id);
if (!seg) continue;
result += seg.finalized ?? seg.pending;
}
return result;
return getTranscriptText(state);
}
// ── Audio buffer capture ──────────────────────────────────────────────────