Skip to content

feat: add peer-bound typed Voice client and owned sessions - #49

Merged
senamakel merged 67 commits into
tinyhumansai:epic/8056-modules-wiringfrom
senamakel:epic-8056-tinyvoice-client-source
Oct 18, 2026
Merged

senamakel merged 67 commits into
tinyhumansai:epic/8056-modules-wiringfrom
senamakel:epic-8056-tinyvoice-client-source

Conversation

@senamakel

Copy link
Copy Markdown
Member

Adds a pure tinyvoice-client contract adapter over published TinyBus SDK 0.3.2. VAD, recorder, hotkey and capture owners bind once to the issuing peer, so a live public-alias handover cannot redirect operations or close a replacement module’s colliding handle. Stateless compatibility methods remain available.

Capture startup uses an explicit reservation owner before the fallible start call. The caller retains that owner across timeout or cancellation and can close it on the same peer, reclaiming a late-published stream. Known unstarted reservations can also be closed. Owned handles perform explicit cleanup; Drop does not dispatch hidden RPC.

Validation:

  • Behavioral VAD/recorder handover and delayed capture-start timeout/cancellation regressions failed before their fixes. Older RED evidence is preserved as explicitly labeled tool-output transcription, not claimed raw log bytes.
  • Final stable Rust 1.99 client suite passed 13/13, including unstarted reservation cleanup. Root and excluded module all-target/all-feature Clippy passed on 1.99 and installed 1.96; formatting, documentation and dependency purity checks passed.
  • The feature matrix passed default/all-feature workspace and excluded-module tests plus package checks. The packaged v0.3.3 module was loaded through the native SDK verifier, which checks real broker routes and portable runtime lifecycle. These latest broad run exits were captured through tool outputs; final focused/Clippy runs have full raw logs.
  • Root independently matched the packaged dylib SHA256 against modules.toml and reviewed the verifier. Native coverage does not claim physical microphone access: device permission defaults deny. Alias/cancellation ownership is tested through the real broker with deterministic fixture services.

The normal client dependency graph contains only the bus contract and minimal SDK features. The module moves to 0.3.3 and the reviewed release caller selects the already merged closed Voice profile; existing main and tag-push release routes are preserved. Hosted checks must pass this PR before release.

Refs senamakel#1
Part of tinyhumansai/openhuman#8056

Update the vendored tinybus submodule to a newer revision.

Auto-committed-on: macbook
Update the vendored tinybus submodule to the latest upstream commit.

Auto-committed-on: macbook
Adds a new workspace member providing a typed TinyBus client for the loadable TinyVoice module, and lists it in the root README alongside the existing crates.

Auto-committed-on: macbook
…or redaction

The mock voice now records calls and can inject failures or canned replies, letting the tests assert exact member names and positional arguments for every stateless wrapper, capture, and hotkey call. New cases verify that VAD and recorder handles close only explicitly, that unexpected intents map to Unknown, and that module errors stay redacted while still reaching the failure sink.

Auto-committed-on: macbook
Adjust the mock voice interface and capture wrapper tests to use plain string capture handles instead of nested handle objects, and access the VAD id as a field rather than a method. Also return a null value for VAD and session close responses to match the updated protocol shapes.

Auto-committed-on: macbook
…d bus paths

Add a mock failure mode that returns an unknown method so the client's
incompatible-contract mapping and failure reporting are exercised, and update
the capture test to use the relocated bus module paths.

Auto-committed-on: macbook
…at tests

The README now explains how to construct the client from the host's single configured ModuleClient and notes that the manifest's TinyBus version range is a draft pending alignment with the 0.3.x runtime. Test code was reformatted to satisfy rustfmt, with no change in behaviour.

Auto-committed-on: macbook
Extend the wrapper test so reserve_capture is exercised alongside reserve_hotkey, asserting that a denied reply surfaces as CaptureError::PermissionDenied and that the recorded call carries the expected permission payload.

Auto-committed-on: macbook
Updated the VAD and recorder routing test to read the recorder's id field instead of calling an accessor, matching the current handle API.

Auto-committed-on: macbook
Update the vendored tinybus submodule to the latest upstream commit.

Auto-committed-on: macbook
Update the tinybus and tinybus-module version constraints to the 0.2.2 release across the client and module crates, and refresh the lockfile accordingly. The client README now reflects the published 0.2.2 API instead of describing the range as a draft against 0.2.1.

Auto-committed-on: macbook
Adds the base64 crate to the client so it can encode and decode binary payloads carried over the bus.

Auto-committed-on: macbook
The client now exposes typed wrappers over the TinyVoice TinyBus module for
routing, gating, audio preparation, VAD, capture, hotkey, and recording
sessions, with a VoiceCallError that keeps untrusted remote prose out of
Debug, Display, and terminal reports unless a caller explicitly asks for it.
serde_json moved from dev-dependencies to dependencies to support the wire
conversions.

Auto-committed-on: macbook
Update the mock interface responses so reserve capture returns a bare
handle string and the gate recording and encode wav expectations use the
exact f32-derived values and base64 payload the client now produces.

Auto-committed-on: macbook
Wrap VAD and recorder session calls in a helper that annotates errors with the failing operation, and give the hotkey and capture denial replies distinct shapes so each wrapper is exercised against its own error format.

Auto-committed-on: macbook
…mats

Adjust the mock voice interface so its canned session advance and capture stop responses use the current typed payload shapes, keeping the wrapper tests aligned with the real protocol.

Auto-committed-on: macbook
The capture wrapper test now unwraps the results of stop_capture and shutdown_capture with expect so a failure surfaces as a clear assertion instead of being silently propagated. An unused Calls type alias was also dropped.

Auto-committed-on: macbook
Replace the hand-expanded f64 constants in the stateless wrapper and VAD push expectations with f32 literals so the test values match the wire types directly and stay readable.

Auto-committed-on: macbook
The client's dev-dependencies no longer enable TinyBus's macros feature, so the tinybus-macros package drops out of the lockfile. The README now documents that the client preserves the configured ModuleClient deadline and reporting sink, and that raw remote values from the error accessors require a caller-owned redaction policy.

Auto-committed-on: macbook
Moved the tinyvoice_bus re-export block below the submodule re-exports and
reformatted several call chains and closures to satisfy rustfmt. No behaviour
changed.

Auto-committed-on: macbook
Rustdoc comments now render the product and bus names as code spans, matching the crate's existing documentation style. No behaviour changed.

Auto-committed-on: macbook
…wire tests

Adds crate-level clippy allows for expect_used and unwrap_used since these behaviour tests intentionally panic on failure, and marks the two long test functions with too_many_lines. The mock interface arms are also consolidated so VAD_IS_SPEAKING and HOTKEY_FEED share their existing replies instead of duplicating them.

Auto-committed-on: macbook
Extend the redaction test to assert that a malformed route reply surfaces as a module fault without leaking the transcript, and add a case confirming proxy startup failures keep the transport classification.

Auto-committed-on: macbook
Replace the explicit path link to `ModuleClient` with an intra-doc link so the crate documentation resolves the type without hardcoding the `tinybus` module path.

Auto-committed-on: macbook
Bumps tinybus and tinybus-macros to 0.2.2, which swaps the zip crate for rawzip and adds icu_casemap and unicode-normalization for case folding and text normalization. The lockfile also picks up the resulting transitive dependency changes.

Auto-committed-on: macbook
Dependency comments now explain why each crate is needed, the duplicate tinybus dev-dependency is dropped, and the unused tokio time feature is removed. Two doc comments were reworded to say the client requests capture shutdown rather than waiting for cleanup.

Auto-committed-on: macbook
Register a new test module for ownership checks in the tinyvoice client
crate so the accompanying test file is compiled and run.

Auto-committed-on: macbook
Reformat the alias-handover regression tests to satisfy rustfmt, moving the
inner attribute above the imports and reflowing long expressions and match
arms. No test behaviour or coverage changed.

Auto-committed-on: macbook
The expected method list in the VAD ownership test now places ROUTE before the VAD methods, matching the order the fixture actually reports.

Auto-committed-on: macbook
Update the vendored tinybus submodule to commit cba2de0 to pick up its latest upstream changes.

Auto-committed-on: macbook
`start_capture_owned` is replaced by `reserve_capture_owned`, which returns an `OwnedCaptureReservation` bound to the pinned peer before any fallible native startup runs. The reservation exposes `start` and `close` so a timed-out or canceled start can still be stopped through the same peer.

Auto-committed-on: macbook
… fixture

The ownership fixture now models a capture start that is still pending when a stop arrives, so tests can exercise cancellation of an in-flight start. Capture poll and stop also return unknown_handle for handles that were never opened instead of relying on a shared assertion helper.

Auto-committed-on: macbook
Extracted a shared helper that reserves and starts an owned capture stream, and replaced the repeated inline setup in the ownership tests with it. Also dropped an unused capture-open helper.

Auto-committed-on: macbook
Rework the ownership tests so the reservation is taken up front and the
retained owner is closed explicitly after a timed-out or canceled start,
asserting the close waits for startup cleanup and leaves no late stream
pollable.

Auto-committed-on: macbook
The README now describes `reserve_capture_owned` returning a pinned reservation before `CAPTURE_START`, with explicit close targeting the creating peer and the existing pending-start cancellation path. The ownership test's expected call order was corrected to match the actual stop-then-poll sequence.

Auto-committed-on: macbook
Reformatted two expressions in the ownership tests to satisfy rustfmt, collapsing a multi-line condition and a spawned future onto single lines. No test behaviour changed.

Auto-committed-on: macbook
…rvations

The ownership fixture now checks the capture reservation handle before
blocking on the gate and returns the capture handle from the gated path
instead of falling through to the generic method dispatch. This keeps the
fixture's state transitions consistent with the real client's reservation
flow.

Auto-committed-on: macbook
Rewrapped the poisoned-state error mapping in the ownership test fixture to satisfy formatting, with no change to behaviour.

Auto-committed-on: macbook
The ownership test fixture now handles the capture stop method, recording the call and resolving pending, stopped, or unknown handles so tests can exercise stop behaviour against the fake interface.

Auto-committed-on: macbook
…t double

The fake interface used by the ownership tests no longer handles the capture stop method, since the tests that exercised that path are gone and the stub was only kept around for them.

Auto-committed-on: macbook
Replace the loose boolean flags in the ownership test fixture with
CaptureFixtureState and HotkeyFixtureState enums so impossible combinations
can no longer be represented. This makes the fixture's lifecycle states
explicit and keeps the tests aligned with the real state machine.

Auto-committed-on: macbook
Reformatted the ownership test fixtures to satisfy rustfmt, wrapping enum variants and error strings and collapsing a few expressions that now fit on one line. No test behaviour changed.

Auto-committed-on: macbook
The ownership test fixture now reports the hotkey as active only when the
requesting peer is B, matching the behaviour the test is meant to exercise.

Auto-committed-on: macbook
…-domain handlers

The ownership test fixture's single large call implementation is now
decomposed into separate VAD, recorder, capture, and hotkey handlers
dispatched by method name, with capture start and stop kept async. This
keeps each fixture domain's state transitions isolated and makes the
dispatch table easier to extend.

Auto-committed-on: macbook
…clippy

Extracted a shared helper for building hotkey status responses in the ownership fixture and applied rustfmt plus clippy allowances so the alias-handover regression tests pass linting without changing their behaviour.

Auto-committed-on: macbook
The ownership test fixture now clones the argument value before pushing it onto the recorded call list, so the original args remain available for the match arms that follow. This keeps the fixture compiling and preserves the recorded calls without moving the value out from under later use.

Auto-committed-on: macbook
The ownership test fixture now passes method arguments by reference instead of by value, and the nested pending/gate check in the capture stop handler is collapsed into a single let-chain. This avoids unnecessary clones in the fixture and keeps the test code aligned with current idioms.

Auto-committed-on: macbook
Closing an owned capture reservation before start now releases the handle on the pinned peer instead of leaving it to expire, and the docs and ownership tests were updated to describe and cover that behaviour.

Auto-committed-on: macbook
The readme now states that the vendored gitlink and both Cargo lockfiles resolve to the published TinyBus 0.3.2 source, replacing the note that the lockfiles still needed refreshing.

Auto-committed-on: macbook
…ership fixture

Collapsed the separate Live and Reserved arms into a single match guard since both reset the capture state to Empty and return false, removing the duplicated logic without changing behaviour.

Auto-committed-on: macbook
The prepare test now expresses the tool timeout as one second via
Duration::from_secs instead of an equivalent millisecond value, and a
redundant clippy expectation for unused async trait impls was dropped
since the lint no longer fires at this boundary.

Auto-committed-on: macbook
Replace the emptiness checks in the VAD and capture/hotkey wrapper tests with
equality assertions against explicitly typed empty vectors, so the expected
element type is pinned down. Also allow the newer unused_async_trait_impl lint
on the VoiceService interface, which is unknown to the crate's Rust 1.88 MSRV.

Auto-committed-on: macbook
@coderabbitai

coderabbitai Bot commented Oct 18, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: e326b2ff-e694-4102-8065-31f1f579c0d3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-18T12:33:27.893848Z ed9d31a PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@tinysweeper

tinysweeper Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Tiny Sweeper review

⚠️ Review failed for ed9d31a4e6ad. the review of #49 did not finish within 900s

@senamakel

Copy link
Copy Markdown
Member Author

@tinysweeper review

The previous review timed out after 900 seconds. Please retry the review at ed9d31a. All 13 build and test jobs passed; the completed Codex review has no findings.

@senamakel
senamakel merged commit 219da45 into tinyhumansai:epic/8056-modules-wiring Oct 18, 2026
14 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant