Repository navigation
Conversation
|
[P2] Confirm audio samples before latching Typecast's receive time ai_agents/agents/ten_packages/extension/typecast_tts_python/typecast_tts.py:98 When the SDK yields a WAV header separately from its PCM payload, this records the header arrival as first audio. [P2] Update Cosy's existing tests for the changed client contract ai_agents/agents/ten_packages/extension/cosy_tts_python/cosy_tts.py:243 Making [P2] Update Typecast's constructor expectation for the supplied session ai_agents/agents/ten_packages/extension/typecast_tts_python/typecast_tts.py:48
[P2] Adapt Oracle's existing response fixture to the streaming read path ai_agents/agents/ten_packages/extension/oracle_tts_python/oracle_tts.py:199
[P2] Add the mandatory audio-end accounting checks to the touched suites ai_agents/agents/ten_packages/extension/cosy_tts_python/tests/test_ttfb_boundary.py:92 (the same gap applies across all 13 touched extension suites) The repository's TTS review test matrix makes exact audio-end accounting a merge requirement for each touched extension. None of these local suites asserts Static review of |
TTS extension reviewReviewed the extension-local changes under |
|
[P2] Wait for a complete WAV signature before recording Oracle audio ai_agents/agents/ten_packages/extension/oracle_tts_python/oracle_tts.py:194 A valid chunked WAV response can initially yield only [P2] Decode HTTP content encodings before recognizing reference audio ai_agents/agents/integration_tests/tts_guarder/tests/provider_ttfb_hooks/http.py:90 This wrapper observes [P2] Complete the mandatory audio-end accounting tests in the touched suites ai_agents/agents/ten_packages/extension/cosy_tts_python/tests/test_ttfb_boundary.py:92 This remains a merge-gate gap across all 13 touched extension suites: none asserts The previously reported Typecast header timing, Cosy caller/test-double signatures, Typecast constructor expectation, and Oracle response-fixture issues also remain unchanged at this HEAD; see the existing findings. The mocked timing-accessor failures remain as well. Static review of |
TTS extension review[P2] Existing mocked metrics tests will break, because the new TTFB accessors return [P2] Mistral, Smallest, EZAI and Sarvam have no extension-local tests for the new timing boundary
Their only coverage is
The other nine extensions in this PR did add such tests. [P3] Import placed above the license header |
TTS extension review (ten-tts-review)Scope: changes under [P2] Attribute StepFun first audio to the request that owns the audio, not the latest sent request [P2] Cover the new TTFB boundary in each changed HTTP extension's own test suite
[P3] Don't mark deterministic mock tests as external API contract tests [P3] Move the StepFun import below the license header Release gate (already acknowledged in the PR): the manifests now pinned to |
|
[P1] Require a base version that provides the new timing APIs ai_agents/agents/ten_packages/extension/cosy_tts_python/cosy_tts.py:13 The latest manifests retain [P2] Confirm PCM before recording Typecast's first audio ai_agents/agents/ten_packages/extension/typecast_tts_python/typecast_tts.py:98 A streaming WAV header can arrive separately from its PCM payload. This records that header as first audio even though [P2] Buffer a possible partial RIFF signature in Oracle's detector ai_agents/agents/ten_packages/extension/oracle_tts_python/oracle_tts.py:194 A valid chunked WAV response may initially yield only [P2] Update Cosy's existing callers and test doubles for the new signature ai_agents/agents/ten_packages/extension/cosy_tts_python/cosy_tts.py:243 Making [P2] Add the required completion and audio-end accounting assertions ai_agents/agents/ten_packages/extension/cosy_tts_python/tests/test_ttfb_boundary.py:92 The new boundary testers stop after first audio and TTFB, before checking completion. Across all 13 touched extension suites, none asserts Static review of |
TTS extension review (ten-tts-review)Scope: the 13 changed TTS extensions under [P1] Raise the
The manifests still accept any
The PR body lists this as a release gate, but the manifest is what enforces compatibility, and once the extension versions are published that gate is gone. Pin the minimum (e.g. [P2] No extension-local tests for the new TTFB boundary in four HTTP adapters
Google, Hume, Typecast, Polly, Oracle, Murf, Cosy, StepFun and OpenAI got such tests in this PR. These four did not. [P3] Oracle can mark first audio on WAV header bytes No ASR paths are touched, so the ASR checklist does not apply. |
|
[P2] Keep hook fixtures runnable in a single-extension guarder app ai_agents/agents/integration_tests/tts_guarder/tests/test_provider_ttfb_hooks.py:54 The normal [P2] Match the Gemini hook to the checked-in adapter's SDK ai_agents/agents/integration_tests/tts_guarder/tests/provider_ttfb_hooks/gemini.py:9 The checked-in [P2] Make the shared tester importable from the standard guarder entry point ai_agents/agents/integration_tests/tts_guarder/tests/test_provider_ttfb.py:17
[P2] Complete the mandatory local audio-end accounting coverage ai_agents/agents/ten_packages/extension/cosy_tts_python/tests/test_ttfb_boundary.py:92 This remains a merge blocker under the repository's required local-test matrix: none of the 13 touched extension suites asserts [P2] Add local adapter timing regressions for the four HTTP extensions ai_agents/agents/ten_packages/extension/smallest_tts_python/smallest_tts.py:250 Smallest, Mistral, EZAI and Sarvam change their transport observation and audio-confirmation boundaries without adding extension-local tests for those changes. Their existing mocked-client metrics tests bypass the real adapters, while The earlier Typecast/Oracle first-audio and test-contract findings, fragmented Oracle header and compressed HTTP reference findings, and mocked timing-accessor failures also remain applicable at this HEAD. Static review of |
e5d9063 to
dda41b8
Compare
|
[P2] Confirm PCM before latching Typecast's first-audio timestamp ai_agents/agents/ten_packages/extension/typecast_tts_python/typecast_tts.py:98 A nonempty SDK chunk can contain only the WAV header, which [P2] Wait for actual audio when Oracle's WAV header is fragmented ai_agents/agents/ten_packages/extension/oracle_tts_python/oracle_tts.py:194 If [P2] Update Cosy's existing callers and test doubles for the new signature ai_agents/agents/ten_packages/extension/cosy_tts_python/cosy_tts.py:243
[P2] Keep hook fixtures runnable in a single-extension guarder installation ai_agents/agents/integration_tests/tts_guarder/tests/test_provider_ttfb_hooks.py:54 The standard [P2] Match the Gemini reference hook to the checked-in SDK adapter ai_agents/agents/integration_tests/tts_guarder/tests/provider_ttfb_hooks/gemini.py:6 The repository's [P2] Add extension-local regressions for the four HTTP timing changes ai_agents/agents/ten_packages/extension/smallest_tts_python/smallest_tts.py:250 Smallest, Mistral, EZAI, and Sarvam add transport observation/audio confirmation without local tests exercising those changes. Their existing metrics tests mock the client, and the shared HTTP integration suite does not satisfy the required extension-local matrix. Drive each real adapter over a deterministic transport and assert exclusion of empty/control chunks, the send-to-first-audio boundary, exactly one metric, and fresh timing for a second request ID. [P2] Complete the mandatory local audio-end accounting coverage ai_agents/agents/ten_packages/extension/cosy_tts_python/tests/test_ttfb_boundary.py:92 This remains a merge-gate gap under the repository's required local-test matrix. None of the 13 touched extension suites asserts The previously reported Typecast constructor expectation and Oracle streaming-fixture failures, compressed HTTP reference decoding defect, and mocked timing-accessor failures also remain present at this HEAD. Reviewed |
TTS extension review[P1] Require the [P2] Add extension-local tests for the new Mistral and EZAI TTFB boundaries
The shared guarder and [P3] Stop dropping the Cosy TTFB metric silently when timing is unavailable |
|
[P2] Keep hook fixtures runnable with only the selected extension installed ai_agents/agents/integration_tests/tts_guarder/tests/test_provider_ttfb_hooks.py:52 The standard [P2] Match the registered Gemini hook to the repository's SDK adapter ai_agents/agents/integration_tests/tts_guarder/tests/provider_ttfb_hooks/gemini.py:9 The checked-in [P2] Decode HTTP content encodings before recognizing reference audio ai_agents/agents/integration_tests/tts_guarder/tests/provider_ttfb_hooks/http.py:102 Wrapping [P2] Update Cosy's existing callers and test doubles for the required request ID ai_agents/agents/ten_packages/extension/cosy_tts_python/cosy_tts.py:244
[P2] Add local regressions for EZAI's and Mistral's new transport timing ai_agents/agents/ten_packages/extension/ezai_tw_tts_python/ezai_tts.py:134 and mistral_tts_python/mistral_tts.py:275 Neither extension's local suite exercises the new request-body trace and audio-confirmation boundary. EZAI's metrics test mocks the whole client; Mistral's uses a mocked raw response and checks only a latency lower bound, bypassing the new SSE branch and real transport hooks. The repository's required local-test matrix does not allow shared integration tests to replace these checks. Drive each real adapter over a deterministic transport and assert exclusion of connection delay and empty/control payloads, exactly one TTFB metric, and fresh timing for a second request ID. [P2] Complete mandatory local audio-end accounting coverage ai_agents/agents/ten_packages/extension/cosy_tts_python/tests/test_ttfb_boundary.py:92 This remains a merge-gate gap under the required extension-local test matrix: none of the six touched extension suites checks Reviewed |
|
[P2] Update Cosy's existing callers and test doubles for the new signature ai_agents/agents/ten_packages/extension/cosy_tts_python/cosy_tts.py:244
[P2] Keep hook fixtures runnable with only the selected extension installed ai_agents/agents/integration_tests/tts_guarder/tests/test_provider_ttfb_hooks.py:52 The normal [P2] Match the Gemini hook to the repository's SDK adapter ai_agents/agents/integration_tests/tts_guarder/tests/provider_ttfb_hooks/gemini.py:9 The checked-in [P2] Decode HTTP content encodings before recognizing reference audio ai_agents/agents/integration_tests/tts_guarder/tests/provider_ttfb_hooks/http.py:102
[P2] Add local regressions for EZAI's and Mistral's transport timing changes ai_agents/agents/ten_packages/extension/ezai_tw_tts_python/ezai_tts.py:134 and mistral_tts_python/mistral_tts.py:275 Neither local suite exercises the new request-body trace and audio-confirmation boundary. EZAI's metrics test mocks the whole client; Mistral's supplies a mocked raw response and checks a latency lower bound, bypassing the new SSE branch and transport hooks. This is a merge-gate gap under the required extension-local test matrix; shared integration tests cannot replace it. Drive each real adapter over a deterministic transport and assert exclusion of connection delay and empty/control payloads, exactly one metric, and fresh timing for a second request ID. Include EZAI's multiple-POST sentence path. [P2] Complete mandatory local audio-end accounting coverage ai_agents/agents/ten_packages/extension/cosy_tts_python/tests/test_ttfb_boundary.py:92 None of the six touched extension suites asserts Reviewed |
TTS extension review[P1] Raise the [P2] Add extension-local tests for the new Mistral and EZAI timing boundaries [P3] Mark the deterministic boundary tests as local tests, not Hook coverage: all six touched extensions are registered in |
|
[P2] Update Cosy's existing callers and doubles for the new client signature ai_agents/agents/ten_packages/extension/cosy_tts_python/cosy_tts.py:244
[P2] Keep hook fixtures runnable with only the selected extension installed ai_agents/agents/integration_tests/tts_guarder/tests/test_provider_ttfb_hooks.py:52 The normal [P2] Match the Gemini hook to the checked-in SDK adapter ai_agents/agents/integration_tests/tts_guarder/tests/provider_ttfb_hooks/gemini.py:9 The repository's [P2] Use one HTTP timing boundary across the new tests ai_agents/agents/ten_packages/extension/openai_tts2_python/tests/test_ttfb_boundary.py:85 The latest HTTP reference starts in the HTTPX request hook, before connection setup, and the shared adapter fixture expects that setup delay to be included. This local test instead timestamps [P2] Decode HTTP content encodings before recognizing reference audio ai_agents/agents/integration_tests/tts_guarder/tests/provider_ttfb_hooks/http.py:102
[P2] Add local regressions for EZAI's and Mistral's new timing paths ai_agents/agents/ten_packages/extension/ezai_tw_tts_python/ezai_tts.py:134 and mistral_tts_python/mistral_tts.py:275 Neither local suite exercises the new transport observation and audio-confirmation boundary. EZAI's metrics test mocks the whole client; Mistral's mocks HTTPX and yields raw bytes, bypassing the changed SSE branch. The required local-test matrix makes this a merge gate; shared integration tests cannot substitute. Drive each real adapter over a deterministic transport and assert the chosen start boundary, exclusion of empty/control payloads, one metric per request, and fresh timing for a second request. Include EZAI's multiple-POST sentence path. [P2] Complete the mandatory local audio-end accounting coverage ai_agents/agents/ten_packages/extension/cosy_tts_python/tests/test_ttfb_boundary.py:92 None of the six touched extension suites asserts Reviewed |
TTS extension review[P1] Update the Cosy local tests for the new
Update these stubs and assertions to match the new signature and TTFB source. Then run the full Cosy local suite, not only [P2] Tighten the [P2] Add extension-local TTFB boundary tests for Mistral and EZAI
[P3] Don't mark the deterministic mock TTFB tests as Guarder hooks: TTFB hooks are registered in |
|
[P1] Require a base version that provides the new HTTP timing APIs ai_agents/agents/ten_packages/extension/openai_tts2_python/openai_tts.py:113 OpenAI, Mistral, EZAI, and Hume now unconditionally call timing methods absent from older [P2] Update Cosy's existing tests for the changed client contract ai_agents/agents/ten_packages/extension/cosy_tts_python/cosy_tts.py:244 The required third argument breaks both calls in [P2] Align the local HTTP tests with the shared timing boundary ai_agents/agents/ten_packages/extension/openai_tts2_python/tests/test_ttfb_boundary.py:85 This fixture records [P2] Keep hook fixtures runnable with only the selected extension installed ai_agents/agents/integration_tests/tts_guarder/tests/test_provider_ttfb_hooks.py:52 The normal guarder task installs one extension through [P2] Match the Gemini reference hook to the repository's SDK adapter ai_agents/agents/integration_tests/tts_guarder/tests/provider_ttfb_hooks/gemini.py:9 The checked-in [P2] Decode HTTP content encodings before recognizing reference audio ai_agents/agents/integration_tests/tts_guarder/tests/provider_ttfb_hooks/http.py:102
[P2] Add local regressions for EZAI's and Mistral's timing paths ai_agents/agents/ten_packages/extension/ezai_tw_tts_python/ezai_tts.py:134 and mistral_tts_python/mistral_tts.py:275 Neither local suite exercises the new transport observation and audio-confirmation boundary. EZAI's metrics test replaces the whole client; Mistral's replaces HTTPX and yields raw bytes, bypassing the changed SSE branch. The required extension-local test matrix makes this a merge gate; shared integration tests cannot substitute. Drive each real adapter over a deterministic transport and assert the chosen start boundary, rejection of empty/control payloads as first audio, one metric per request, and fresh timing for a second request. Include EZAI's multiple-POST sentence path. [P2] Complete the mandatory local audio-end accounting coverage ai_agents/agents/ten_packages/extension/cosy_tts_python/tests/test_ttfb_boundary.py:92 None of the six touched extension suites checks Reviewed |
TTS extension review (
|
|
[P1] Keep the new HTTP clients compatible with their declared base dependency ai_agents/agents/ten_packages/extension/openai_tts2_python/openai_tts.py:113 An app locked to an older [P2] Update the existing Cosy tests for the changed client contract ai_agents/agents/ten_packages/extension/cosy_tts_python/cosy_tts.py:243 The new required [P2] Align the local HTTP timing fixtures with the request-start contract ai_agents/agents/ten_packages/extension/openai_tts2_python/tests/test_ttfb_boundary.py:85 This fixture records [P2] Decode HTTP content encoding before recognizing reference audio ai_agents/agents/integration_tests/tts_guarder/tests/provider_ttfb_hooks/http.py:117 The wrapper captures [P2] Add extension-local coverage for the Mistral and EZAI timing paths ai_agents/agents/ten_packages/extension/mistral_tts_python/mistral_tts.py:275 Neither extension receives a local regression test for its new timing behavior. Mistral's existing metrics fixture returns raw bytes, bypassing this SSE audio-confirmation path; EZAI's fixture mocks the entire client, bypassing both new calls. Add local tests driving the real adapters over deterministic transports, covering empty/control payloads before audio, exactly one TTFB for each of two sequential request IDs, and EZAI's multi-sentence/multi-POST path. The required local-test matrix explicitly says shared integration cases cannot substitute for extension-local coverage. [P2] Complete the mandatory local audio-end accounting coverage ai_agents/agents/ten_packages/extension/cosy_tts_python/tests/test_ttfb_boundary.py:92 None of the six touched extension suites asserts Validation: reviewed HEAD |
|
TTS extension review ( Scope: the six changed TTS extensions under [P2] Start Cosy's TTFB after DashScope session setup, not before Two things hide this:
Fix: stamp the send time after the stream has started. For example, warm the session explicitly before the timed call if the SDK exposes a way to do that, or record the time on the first Still open at this HEAD (reported earlier, unchanged)
Guarder hooks: all six extensions are registered in Static review of |
|
[P2] Update Cosy's existing tests for the changed client contract ai_agents/agents/ten_packages/extension/cosy_tts_python/cosy_tts.py:243 The required [P2] Complete the mandatory local audio-end accounting coverage ai_agents/agents/ten_packages/extension/openai_tts2_python/tests/test_ttfb_boundary.py:66 This tester stops after first audio and TTFB, before checking request completion; the new Google, Hume, and Cosy testers have the same limitation. None of the six touched extension-local suites asserts Validation: reviewed HEAD |
TTS extension review (
|
b1d2bbf to
84599cf
Compare
|
[P2] Update Cosy's timing fixture and observer for pooled synthesizers ai_agents/agents/ten_packages/extension/cosy_tts_python/tests/test_ttfb_boundary.py:125 The current client obtains synthesizers through [P2] Provide an independent HTTP provider timing reference ai_agents/agents/ten_packages/extension/openai_tts2_python/manifest.json:4 The required hook coverage for this release, Mistral, EZAI and Hume delegates to [P2] Complete the required terminal audio-accounting tests ai_agents/agents/ten_packages/extension/google_tts_python/tests/test_ttfb_boundary.py:65 This tester stops after first audio and TTFB, without checking completion. Google, OpenAI, Hume, Mistral and EZAI have no local assertion of Validation: reviewed HEAD |
|
TTS extension review [P2] Cosy TTFB hook and local test patch a class the adapter never constructs
The same problem affects the new extension test. The fake To fix this, hook the pooled object instead, either by patching [P2] Hume: injecting a custom The Hume SDK is Fern-generated. In Fern clients, the wrapper timeout defaults to 60 only when Please check this against [P3] Cosy Nothing imports [P3] Cosy changes ship without the described version bump, and the The PR body says "Cosy is 0.4.3 -> 0.4.4". On main, Cosy is at Cosy [P3] Local TTFB tests allow 5 ms against the stated 1 ms contract, and mock-only tests are marked
Notes
|
|
[P2] Keep hook fixtures independent of unselected vendor packages ai_agents/agents/integration_tests/tts_guarder/tests/test_provider_ttfb_hooks.py:22 The default guarder command installs only the selected extension through [P2] Update Cosy's timing test and observer for pooled synthesizers ai_agents/agents/ten_packages/extension/cosy_tts_python/tests/test_ttfb_boundary.py:125 The current client creates a [P2] Provide HTTP timing references independent of adapter decoding ai_agents/agents/ten_packages/extension/humeai_tts_python/humeTTS.py:37 (also affects the touched OpenAI and Mistral adapters) These adapters' required coverage delegates to [P2] Complete the required terminal audio-accounting tests ai_agents/agents/ten_packages/extension/google_tts_python/tests/test_ttfb_boundary.py:66 This tester stops after first audio and TTFB, before checking request completion. Google, OpenAI, Hume and Mistral have no extension-local assertion of Validation: static review of HEAD |
TTS review (ten-tts-review)Scope: the in-scope TTS extensions are [P2] Fix the Cosy TTFB test so it does not reach DashScope [P2] Fix the Cosy guarder TTFB hook for the pooled SDK path [P3] Wire up or remove Note: |
|
[P2] Exercise Cosy pooled synthesizers in the test and timing hook cosy_tts_python/tests/test_ttfb_boundary.py:124 Cosy now borrows synthesizers from [P2] Keep guarder fixtures independent of unselected extensions test_provider_ttfb_hooks.py:22 The default guarder installation selects one extension and runs the whole test directory. This fixture unconditionally imports the Google adapter, so a clean run for another provider fails with [P2] Capture independent HTTP provider timing references humeTTS.py:37 (also affects the touched OpenAI and Mistral adapters) The registered [P2] Complete terminal audio-accounting coverage in the touched suites google_tts_python/tests/test_ttfb_boundary.py:66 This tester stops after first audio and TTFB, before completion. The required extension-local matrix calls for exact emitted-PCM duration, controlled-clock Correction to the earlier Hume timeout concern: Static review of HEAD |
|
TTS extension review (scope: files under [P2] Cosy TTFB hook never observes production traffic [P2] Cosy local TTFB test mocks a constructor the extension doesn't call [P2] Injecting [P3] [P3] Description and version changes don't match the diff
Please align the versions and the description with what actually changes. [P3] New mock-only tests are marked |
|
[P2] Exercise the pooled Cosy client in the local test and TTFB reference cosy_tts_python/tests/test_ttfb_boundary.py:124 Cosy obtains its synthesizer from [P2] Measure an independent HTTP provider boundary humeai_tts_python/humeTTS.py:37 (also OpenAI and Mistral) The registered HTTP hook timestamps entry to the production [P2] Complete terminal audio-accounting coverage in the touched suites google_tts_python/tests/test_ttfb_boundary.py:66 This tester stops after first audio and TTFB, before completion. Google, OpenAI, Hume and Mistral lack local Static review of HEAD |
TTS extension review[P2] Cosy TTFB hook and local test patch a constructor the adapter never calls
Fix direction: hook the boundary the adapter actually uses. Either patch [P2] Hume: injecting an external Fern-generated clients such as [P3] Cosy ships an unused Nothing imports Notes (non-blocking)
Out of scope per the TTS review skill: |
|
[P2] Install the Cosy fake and reference on the pooled synthesizer cosy_tts_python/tests/test_ttfb_boundary.py:124 (also provider_ttfb_hooks/cosy.py:33) The adapter obtains synthesizers through [P2] Measure HTTP TTFB at an independent provider boundary humeai_tts_python/humeTTS.py:37 (also the touched OpenAI and Mistral extensions) The registered HTTP hook observes entry to the production adapter [P2] Avoid importing Google in every provider guarder run test_provider_ttfb_hooks.py:22 The default guarder command runs the entire [P2] Cover terminal audio accounting in the touched extension suites google_tts_python/tests/test_ttfb_boundary.py:66 The new tester stops after first audio and TTFB, before completion. Google, OpenAI, Hume and Mistral lack local Static review of head |
|
TTS review: findings Reviewed against [P2] Cosy TTFB hook and local test patch a constructor the extension never calls [P3] Unused [P3] [P3] Google TTFB change is covered only on the single-request success path
Please add these cases next to Notes (not blocking)
|
|
[P2] Measure HTTP TTFB against an independent provider boundary ai_agents/agents/ten_packages/extension/humeai_tts_python/humeTTS.py:37 (also OpenAI and Mistral) The registered HTTP hook captures entry to the production adapter [P2] Avoid requiring Google for every default guarder run ai_agents/agents/integration_tests/tts_guarder/tests/test_provider_ttfb_hooks.py:22 The default guarder command runs all of [P2] Cover terminal audio accounting in the touched extension suites ai_agents/agents/ten_packages/extension/google_tts_python/tests/test_ttfb_boundary.py:66 The new tester stops after first audio and TTFB, before completion. The Google, Hume, Mistral and OpenAI extension-local suites do not assert Static review of |
|
TTS extension review (ten-tts-review) In scope: [P2] Use a send-boundary reference for the HTTP TTFB hooks instead of re-wrapping [P2] Cover the new Google TTFB state transitions with local tests
Separately, the Google suite has no assertion on [P3] Make version bumps match the actual changes and update the stale PR description
Hume, Mistral and OpenAI rely on base-side TTFB and keep the Minor
ASR checklist: N/A. No ASR extensions are touched. |





Problem
Several TTS adapters measured TTFB outside the provider boundary, including connection setup, buffering, conversion, or queueing time. The second-stage adapters need provider-boundary timing checks while keeping the existing
0.7dependency range.Goal
Update the second-stage timing implementation for Google, OpenAI, Mistral, EZAI, Hume, and Cosy. Each changed extension receives one patch-version increment. The shared timing implementation is provided by
ten_ai_base0.7.63 after publication.Design rationale
HTTPX transport hooks record the request-body send boundary, and adapter-level observers confirm the first real audio payload for structured responses. SDK hooks use public calls, lazy input consumption, and first nonempty audio callbacks. Opaque SDK-internal socket timing is not inferred. Protocol decoding is deferred away from the provider I/O callback.
Validation
The guarder uses the same entry point as the first stage:
task tts-guarder-test EXTENSION=openai_tts2_python -- \\ -k test_sequential_requests_ttfb -m api --strict-markers -v --tb=shortThe selected case sends two sequential request IDs, with a single final text in the second request. It checks actual audio, completion, one TTFB metric per request, the tester send-to-first-audio bound, and agreement with the independent provider-boundary reference within 1 ms.
Deterministic validation passed in the container:
Live credentialed verification for this phase currently has these results:
qwen-audio-3.1-tts-flashand voiceqwen-audio-3.1-tts-flash-miaomiao-ecf86958296b421da34abe84a88f67e7.neuralengine is unsupported in the selected region.The two failed providers and five providers without credentials are outside this PR. Their production code, extension tests, and guarder hooks were reverted to the main branch. No live pass is claimed for them.
Release gate
Draft until shared base 0.7.63 and the updated extension versions are published. No package was published. Install and registry compatibility must be checked after publication; focused tests used local prepared packages.
Package version policy
All thirteen changed TTS versions increment the remote-main patch version exactly once. Cosy is 0.4.3 -> 0.4.4. Each extension keeps its original
ten_ai_base0.7minor range, and extension pyproject versions match manifests. This PR does not pin extensions to0.7.63.Rebase status
Rebased onto main after the first-stage PR merged. The shared first-stage tester and 1 ms assertions now cover the second-stage provider hooks through the normal
task tts-guarder-testentry point. Details and limitations are documented intts_guarder/tests/PROVIDER_TTFB.md.CI follow-up
Fixed the Google TTS Pylint
W0640by binding each retry's request generator when the timing wrapper is created. The fix is in commita7f0b3d77. Google source Pylint now passes in the container. The local extension test collection requires the prepared TEN runtime package and was not run from the uninstalled worktree.