Skip to content

feat: emit recognizer_loop:audio_output_start in _mock_tts alongside audio_output_end#108

Merged
JarbasAl merged 5 commits into
devfrom
docs/mocktts-singleton-rationale
Jun 29, 2026
Merged

feat: emit recognizer_loop:audio_output_start in _mock_tts alongside audio_output_end#108
JarbasAl merged 5 commits into
devfrom
docs/mocktts-singleton-rationale

Conversation

@JarbasAl

Copy link
Copy Markdown
Member

The TTS mock previously only emitted recognizer_loop:audio_output_end (unduck) after a delay, missing the recognizer_loop:audio_output_start (duck) that a real TTS playback emits when speech begins.

Now _mock_tts emits audio_output_start synchronously on speak (TTS begins) and audio_output_end after 100ms (TTS finishes), properly simulating the full duck/unduck lifecycle.

This is needed by ovos-core PR #788 (feat/pipeline1-handler-trio) which asserts exact bus message sequences — the missing start event was asymmetrical and would cause false negatives in tests that expect both signals.

JarbasAl and others added 2 commits June 29, 2026 15:20
recognizer_loop:audio_output_end is a real bus message in production
(emitted by the audio service), so the harness now publishes it the same
way — plain bus.emit through on_message — instead of bus.ee.emit, which
bypassed namespace migration and the capture path.

This is now safe and correct because ovos-bus-client's SessionManager keeps
one live Session per id (mutates in place, no wholesale replace), so routing
through on_message no longer clobbers transient session state;
handle_audio_output_end flips is_speaking=False on the shared singleton.

Capture position is faithful to a real deployment: with speak(wait=False)
the handler emits its end-marker first, so audio_output_end lands after the
EOF and is not captured; with speak(wait=True) the handler blocks in
wait_while_speaking until it arrives, so it deterministically precedes the
end-marker and is captured — as any real bus observer would record it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The TTS mock previously only emitted recognizer_loop:audio_output_end
(unduck) after a delay, missing the recognizer_loop:audio_output_start
(duck) that a real TTS playback emits when speech begins.

Now _mock_tts emits audio_output_start synchronously on speak (TTS
begins) and audio_output_end after 100ms (TTS finishes), properly
simulating the full duck/unduck lifecycle.
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@JarbasAl, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 19 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 50d46470-0425-4eb2-8b35-2ba2a8f65c10

📥 Commits

Reviewing files that changed from the base of the PR and between 5e79e57 and ec8a028.

📒 Files selected for processing (3)
  • ovoscope/__init__.py
  • test/unittests/test_end2end.py
  • test/unittests/test_end2end_extended.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/mocktts-singleton-rationale

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown

Another day, another set of automated checks. Let's see! 🌅

I've aggregated the results of the automated checks for this PR below.

🏷️ Release Preview

A sneak peek into the future! 🔮

Current: 1.2.0a1Next: 1.3.0a1

Signal Value
Label feature
PR title feat: emit recognizer_loop:audio_output_start in _mock_tts alongside audio_output_end
Bump minor

✅ PR title follows conventional commit format.


🚀 Release Channel Compatibility

Predicted next version: 1.3.0a1

Channel Status Note Current Constraint
Stable Not in channel -
Testing Too new (must be <1.0.0) ovoscope>=0.7.2,<1.0.0
Alpha Compatible ovoscope>=1.2.0a1

⚖️ License Check

I've checked the genealogical tree of your licenses. 🌳

✅ No license violations found.

Policy: Apache 2.0 (universal donor). StrongCopyleft / NetworkCopyleft / WeakCopyleft / Other / Error categories fail. MPL allowed.

🔍 Lint

I've distilled the results into this summary. 🧪

ruff: issues found — see job log

🔒 Security (pip-audit)

Scanning the horizon for any zero-day threats. 🌅

✅ No known vulnerabilities found (78 packages scanned).

📋 Repo Health

Checking if we're following maintenance best practices. 📏

✅ All required files present.

Latest Version: 1.2.0a1

ovoscope/version.py — Version file
README.md — README
LICENSE — License file
pyproject.toml — pyproject.toml
⚠️ setup.py — setup.py
CHANGELOG.md — Changelog
ovoscope/version.py has valid version block markers

🔨 Build Tests

The build report is now ready for your review. 📝

✅ All versions pass

Python Build Install Tests
3.10
3.11
3.12
3.13
3.14

📊 Coverage

A forensic look at what's being executed. 🔎

53.2% total coverage

Files below 80% coverage (17 files)
File Coverage Missing lines
ovoscope/simple_listener.py 0.0% 55
ovoscope/tts_intelligibility.py 0.0% 190
ovoscope/version.py 0.0% 5
ovoscope/intent_cases.py 14.0% 141
ovoscope/classic_listener.py 18.2% 117
ovoscope/pipeline.py 31.0% 78
ovoscope/ocp.py 31.8% 58
ovoscope/cli.py 32.8% 162
ovoscope/e2e.py 34.9% 99
ovoscope/pytest_plugin.py 41.4% 222
ovoscope/listener.py 56.2% 123
ovoscope/media.py 57.2% 101
ovoscope/voice_loop.py 58.3% 115
ovoscope/__init__.py 58.9% 310
ovoscope/coverage.py 63.3% 69
ovoscope/audio.py 64.2% 112
ovoscope/media_provider.py 64.9% 20

Full report: download the coverage-report artifact.


Your loyal script, at your command 🫡

JarbasAl and others added 2 commits June 29, 2026 18:29
The _mock_tts TTS mock now emits both recognizer_loop:audio_output_start
(synchronous duck) and recognizer_loop:audio_output_end (delayed unduck)
for every speak. Add both topics to HANDLER_LIFECYCLE ignore lists so
unit tests that count messages and test routing don't see them.

Also propagate source/destination from the original speak message into
the mock's emitted context so routing assertions (source/dst matching)
still pass.
@JarbasAl JarbasAl marked this pull request as ready for review June 29, 2026 17:42
@JarbasAl JarbasAl merged commit 42975d0 into dev Jun 29, 2026
13 checks passed
@JarbasAl JarbasAl deleted the docs/mocktts-singleton-rationale branch June 29, 2026 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant