//! # rutster-tap
//!
//! The agent tap: core-as-client + brain-as-server (spec §2, ADR-0006).
//! Slice-1 pre-paved the seam by exposing the canonical PCM boundary as
//! the `AudioSource` / `AudioSink` traits in [`rutster_media`](../rutster-media/index.html),
//! wired by an in-process `EchoAudioPipe`. Slice-2 (this crate) swaps that
//! pipe for a real WSS tap client. No code changes to `RtcSession` itself
//! in step 2 — that's the test of the seam (slice-1 §3.3).
//!
//! # Layout
//!
//! - [`protocol`]: the versioned JSON event wire format (spec §3). PCM
//!   is base64-encoded little-endian i16 (spec §3, §9).
//! - `tap_audio_pipe` (Task 3): the sync `AudioSource`/`AudioSink` impl over
//!   mpsc + a bounded playout ring (spec §4.1). The seam object `RtcSession`
//!   holds; the slice-1 `loop_driver` calls it via `next_pcm_frame` /
//!   `on_pcm_frame` exactly as before.
//! - `tap_client` (Task 3/4): the async WSS connection driver. Runs inside the
//!   `TapEngine` task (in the binary crate); the media loop never sees it.
//! - `metrics` (Task 4): atomic counters — the "observe" half of "drop +
//!   observe" (slice-1 §3.8 extended to the tap wire).
//!
//! # Dependency direction
//!
//! `rutster-tap` → `rutster-media` (re-exports `PcmFrame`; one canonical
//! home — spec §2.1). `rutster-media` does NOT depend on `rutster-tap`
//! — that would invert the canonical-home of `PcmFrame` and pull the
//! loopback peer into the tap story.

pub mod metrics;
pub mod protocol;
pub mod tap_audio_pipe;
pub mod tap_client;

// Re-export PcmFrame so `rutster-tap` consumers (the binary, the echo brain,
// future brains) get it from one canonical home (spec §3.1).
pub use rutster_media::PcmFrame;

pub use metrics::{MetricsSnapshot, TAP_PLAYOUT_FRAMES, TapMetrics};
pub use protocol::{
    AudioPayload, DecodedFrame, DecodedPayload, Envelope, ErrorPayload, FrameKind, HelloPayload,
    PROTOCOL_VERSION, Payload, ReasonPayload, SAMPLES_PER_FRAME as WIRE_SAMPLES_PER_FRAME,
    SessionEndPayload, TapProtoError, decode_envelope, decode_pcm, encode_audio_in,
    encode_audio_out, encode_bye, encode_error, encode_function_call, encode_function_call_output,
    encode_hello, encode_pcm, encode_session_end, encode_speech_started, encode_speech_stopped,
    encode_tools_update,
};
// Slice-3 additive (spec §3).
pub use protocol::{FunctionCallOutputPayload, FunctionCallPayload, ToolsUpdatePayload};
pub use tap_audio_pipe::TapAudioPipe;
pub use tap_client::{FunctionCallEvent, FunctionCallOutputEvent, TapClientError, run_tap_client};

#[cfg(test)]
mod tests {
    #[test]
    fn crate_compiles() {}
}
