Add word-level timestamps and confidence scores

- New word_timestamps option (default False) in client handshake
- When enabled, each segment includes 'words' array with per-word
  start/end times and probability scores
- Wired through entire pipeline: client → server → backend → transcribe()
- Words include timestamp_offset for accurate absolute times
- REST API already supported word timestamps; now WebSocket does too
- Added 9 unit tests for word timestamp extraction and formatting
This commit is contained in:
Aaron Boxer
2026-04-17 10:18:19 -04:00
committed by Aaron Boxer
parent 18de3eacc7
commit 4e31f8c61b
6 changed files with 162 additions and 22 deletions
+18 -17
View File
@@ -43,24 +43,25 @@ class TestClientWebSocketCommunication(BaseTestCase):
class TestClientCallbacks(BaseTestCase):
def test_on_open(self):
expected_message = json.dumps({
"uid": self.client.uid,
"language": self.client.language,
"task": self.client.task,
"model": self.client.model,
"use_vad": True,
"send_last_n_segments": 10,
"no_speech_thresh": 0.45,
"clip_audio": False,
"same_output_threshold": 10,
"enable_translation": False,
"target_language": "fr",
"hotwords": None,
"enable_diarization": False,
"max_speakers": 10,
})
self.client.on_open(self.mock_ws_app)
self.mock_ws_app.send.assert_called_with(expected_message)
self.mock_ws_app.send.assert_called_once()
sent_message = json.loads(self.mock_ws_app.send.call_args[0][0])
self.assertEqual(sent_message["uid"], self.client.uid)
self.assertEqual(sent_message["language"], self.client.language)
self.assertEqual(sent_message["task"], self.client.task)
self.assertEqual(sent_message["model"], self.client.model)
self.assertTrue(sent_message["use_vad"])
self.assertEqual(sent_message["send_last_n_segments"], 10)
self.assertAlmostEqual(sent_message["no_speech_thresh"], 0.45)
self.assertFalse(sent_message["clip_audio"])
self.assertEqual(sent_message["same_output_threshold"], 10)
self.assertFalse(sent_message["enable_translation"])
self.assertEqual(sent_message["target_language"], "fr")
self.assertIsNone(sent_message["hotwords"])
self.assertFalse(sent_message["enable_diarization"])
self.assertEqual(sent_message["max_speakers"], 10)
self.assertFalse(sent_message["word_timestamps"])
def test_on_message(self):
message = json.dumps(