Repository navigation
feat(asr): add stepfun asr - #2364
diyuyi-agora wants to merge 28 commits into
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
ASR design review(re-review @ 06a6db7)针对上一轮 P1: 静态核对(06a6db7d)
ASR checklist
Findings(P1/P2 merge blockers)无。 REVIEW PASS |
* feat(tts-guarder): cover more vendors in subtitle timing checks Add vendor timing hooks for Cartesia, ElevenLabs, ByteDance and the ByteDance duplex client. Each hook captures provider word times at its own client boundary and hands them to the shared checker, so the timestamps a vendor converts can be compared with the original data: Cartesia and ElevenLabs through the client's websocket dependency, ByteDance at the session response handler. The checker keeps only results that carry spoken text, because a terminal result may hold a synthetic placeholder word that marks the end of a request instead of describing speech. The guide and the timing notes now describe the registered observers and the coverage levels. * fix(cartesia-tts): retain subtitle sequence until terminal result The per-request sequence counter was released on audio completion and on error, but the vendor's final timestamp can arrive after that release. The terminal subtitle then restarted from zero, so consumers saw the sequence move backwards. The counter is now kept until the terminal subtitle result has been emitted. Bump the extension version to 0.8.6. * fix(tts-guarder): keep ElevenLabs word separators in the timing hook The hook trimmed trailing whitespace from every alignment packet, so a space that separates two words was dropped from the reference words and the comparison against TEN output drifted. Trailing whitespace is now treated as padding only when it reaches past the audio already delivered, which mirrors how the extension builds the same timestamps. * fix(tts-guarder): measure subtitle ranges by the spoken words The ElevenLabs client appends padding whitespace after the last spoken word and that padding can reach past the delivered audio, so the range check rejected a request the provider had finished normally. Ranges and word counts are now measured up to the last word that carries text, and the vendor hook reports provider words untouched. * fix(cartesia-tts): release sequence counters of finished requests A vendor error can end a request before its final timestamp arrives, so the per-request counter is kept until the terminal subtitle. Interrupted or failed requests never receive one, which left their entries behind for the lifetime of the extension. An interrupted request now releases its counter with the audio_end event, and the counters of earlier requests are dropped when the next request starts. A late terminal timestamp for the live request can therefore still continue its sequence instead of restarting at zero. * test(cartesia-tts): cover subtitle sequence and audio-end accounting The state-machine fakes never enqueue subtitle words, so nothing asserted the sequence counters or the audio-end fields. The new cases drive the transcription consumer, the request path, and the interrupted path, then check the emitted results, the released counters, exactly one audio_end with the duration of the emitted PCM bytes, and the event interval measured on a controlled clock. * fix(tts-guarder): read provider word times at the transport boundary The ByteDance hooks built their expected times from the converted TEN words and from the extension's sentence bookkeeping, so a conversion defect moved the reference and the compared output together and was accepted. Both references are now built from the provider's own word fields and from the audio bytes counted at its sentence boundaries: the session's frontend messages for ByteDance, and the client's server messages for the duplex variant, which also removes the private extension state it used to read. Also in this area: - ElevenLabs alignment times are relative to each request, so the origin is reset with the rest of the per-request capture instead of carrying the previous request's first-character offset. - Cartesia spacing mirrors the client again: one space at each timestamp group boundary and no space around CJK or punctuation, matching the client's own spacing fixtures. The duplex provider sends turn-relative times and the extension aligns each sentence's first word with that sentence's audio start. The reference mirrors that alignment, and SUBTITLE_TIMING.md now records what that costs. * test(tts-guarder): pin hook spacing, origins, and sentence positions The hooks build the reference that the live subtitle case compares against TEN output, so their spacing rules and request bookkeeping are now checked without a provider connection: the Cartesia spacing fixtures from the client's own tests, a per-request ElevenLabs origin, and the ByteDance sentence positions and word offsets. * feat(tts-guarder): cover the ElevenLabs text-to-dialogue protocol The extension selects the text-to-dialogue client for models outside the v2 family. The timing hook now follows that choice: it installs the observer on the module the config selects, reads the snake_case message fields, and builds the reference the way TTD reports it, with character times restarting at zero in every chunk and continuing from the previous chunk's text. The subtitle case runs once per provider configuration, so a vendor can keep a TTS config and add an alignment-enabled TTD config next to it. The conftest also drops the removed _pytest.config.Notset import so the suite loads on the pytest shipped with the current build image. * test(tts-guarder): report the subtitle bounds in the range diagnostic A rejected subtitle range only said it was outside the PCM timeline. The diagnostic now carries the result start, duration, spoken end, and the PCM window, which is enough to tell a provider tail overshoot from a shifted conversion without adding a probe. * feat(tts-guarder): cover the Azure TTS subtitle case `azure_tts` is a C++ extension that lives in the conversational agent tree, so its runs copy this guarder there and keep the subtitle configuration in that tree. Adding it to the supported list lets the case run once that configuration is present, with the generic alignment checks: the Speech SDK boundary is inside the compiled extension and has no Python hook point. The docs record the copy-and-run workflow, the coverage level, and where the configuration lives.
…2362) * feat(asr): enhance Soniox ASR websocket client with API key support * feat(asr): upgrade soniox asr to 0.6.4 --------- Co-authored-by: hanhandi <1540984562@qq.com>
* feat(bridge): add Agora Mind TEN bridge extension * test(bridge): cover Agora Mind message translation * fix(bridge): match repository black formatting * fix(bridge): declare object metadata schema
Preserve finalize/audio order across reconnect buffers, complete finalize after fatal errors, keep originating session metadata for late finals, and harden reconnect/error/journal bookkeeping with contract tests. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep reconnect retries under one owner, stamp session metadata on server-VAD spans, claim finalize completion before awaits, separate journal ownership from delivery for TTFW, and fix standalone test paths. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Prevent cross-session empty finalize claims, retain in-flight replay mappings, invalidate connect attempts on stop, and unify normal-close handling with contract coverage. Co-authored-by: Cursor <cursoragent@cursor.com>
Wait for in-flight connects before recovery retry, keep open-span session ownership across finalize, retain confirmed replay spans before remapping, and sanitize config validation errors. Co-authored-by: Cursor <cursoragent@cursor.com>
Seal queued audio after finalize timeout, retire confirmed replay spans on replacement finals, preserve normal-close after startup, and lock result/finalize context across awaited metrics output. Co-authored-by: Cursor <cursoragent@cursor.com>
Require vendor commit on local VAD session seals, journal frames before dump, and route on_data finalize under the result-context lock. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep finalize boundaries in input order, call the base on_data hook, serialize live audio metadata with result metrics, and tolerate replay finals without optional word timestamps. Co-authored-by: Cursor <cursoragent@cursor.com>
Inherit audio session context when finalize omits metadata, acknowledge empty finalize_id, and keep structured WS rejections on a single fatal path. Co-authored-by: Cursor <cursoragent@cursor.com>
Defer omitted finalize metadata until preceding audio is consumed, and avoid restoring stale session context over live input during finalize-end. Co-authored-by: Cursor <cursoragent@cursor.com>
…paths Serialize asr_finalize_end with result context lock and add regressions for metadata-less finalize when the consumer is delayed or in a fatal state. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep finalize emit metadata within the dequeued boundary, prefer queued or discarded context over stale journal spans on fatal/timeout paths, and pin asr_result ids per transcript segment with regression tests. Co-authored-by: Cursor <cursoragent@cursor.com>
Hold result context only for metadata updates during audio send, count finalize deadlines from enqueue time, backfill session_id for partial finalize metadata, and add blocked-send and trace-id regressions. Co-authored-by: Cursor <cursoragent@cursor.com>
Serialize send_audio metadata updates with result context, avoid re-registering finalize contexts after timeout seal, and add recovery-flush metrics and context cleanup regressions. Co-authored-by: Cursor <cursoragent@cursor.com>
cdc08fd to
afbd434
Compare
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
Use block-level protected-access suppressions so black does not split inline comments and break CI lint. Co-authored-by: Cursor <cursoragent@cursor.com>
ce0c07a to
a61238c
Compare
ASR checklist
These issues remain present at |
This comment was marked as outdated.
This comment was marked as outdated.
ASR checklist
Reviewed at |
|
Review: StepFun ASR ( Reviewed against Merge blockers (MUST)
Should fix
ASR checklist
|
ASR checklist
Reviewed head |
No description provided.