pub trait WireAdapter {
type Frame;
type Event;
type Response;
// Required methods
fn classify(&self, frame: Self::Frame) -> WireEvent<Self::Event>;
fn interpret(
&mut self,
event: Self::Event,
out: &mut AdapterOutput<Self::Response>,
);
fn finish(&mut self, out: &mut AdapterOutput<Self::Response>);
// Provided methods
fn flush_before_terminal_error(
&mut self,
_out: &mut AdapterOutput<Self::Response>,
) { ... }
fn is_finished(&self) -> bool { ... }
}Expand description
One streaming wire family as a thin adapter onto the canonical grammar.
classify and interpret are sans-IO by construction: no transport
handle, no async — pure (state, event) → events functions, testable by
feeding events directly with no mock HTTP.
§Contract for implementors (in-tree and out-of-tree)
This trait is public so companion provider crates (rig-bedrock,
rig-gemini-grpc, rig-candle) and out-of-tree providers implement it and
inherit the shared run_wire_stream / run_wire_buffered drivers.
An implementation must uphold:
- Classify delegation:
WireAdapter::classifydelegates to awire.rsclassifier — never raw serde — so decode-then-validate policy is stated once per wire family. - Driver-owns-policy: unknown/corrupt-frame handling belongs to the
driver (module policy table); adapters contain no
match WireEvent. - Mandatory identity: every
Reasoning/ReasoningDelta,ToolCallDelta, andTextStartevent carries aStreamPartId— the wire’s own identity (StreamPartId::Wire) when it exists, else an identity minted viaSyntheticIds(StreamPartId::Minted). Provenance travels in the type: a minted identity keys stream accumulation and structurally cannot become a durable provider handle or reach a request serializer, so no per-provider gate exists or is needed. - Finish/flush obligations: see
WireAdapter::finish(EOF-only, never synthesizes a terminal) andWireAdapter::flush_before_terminal_error(fully-delivered content only, no terminal record). WireAdapter::is_finished:trueonly afterinterpretconsumed the wire’s own in-band terminal failure, having pushed the flush-then-Errsequence itself.
Required Associated Types§
Sourcetype Frame
type Frame
The transport frame this adapter classifies: WireFrame for byte
wires (SSE, NDJSON, websocket), the SDK’s own event type for
typed-transport wires (bedrock’s Converse events, gemini-grpc’s
protobuf responses, candle’s in-process generation events).
Sourcetype Response
type Response
The provider-native terminal record carried by
RawStreamingChoice::FinalResponse.
Required Methods§
Sourcefn classify(&self, frame: Self::Frame) -> WireEvent<Self::Event>
fn classify(&self, frame: Self::Frame) -> WireEvent<Self::Event>
Decode + classify one transport frame. MUST delegate to a wire.rs
classifier (classify_tagged_frame / classify_chat_completions_frame
/ classify_untyped_line / classify_typed_event) — never raw serde,
so the decode-then-validate policy cannot be re-derived per adapter.
Sourcefn interpret(
&mut self,
event: Self::Event,
out: &mut AdapterOutput<Self::Response>,
)
fn interpret( &mut self, event: Self::Event, out: &mut AdapterOutput<Self::Response>, )
Map one Known event to canonical grammar events. Stateful: index→id
maps, open-block state, id fabrication, and wire-quirk quarantine live
here — policy for unknown/corrupt frames does not (the driver owns it).
Pushing a RawStreamingChoice::FinalResponse marks the provider’s
genuine terminal; the driver stops consuming after yielding it.
Sourcefn finish(&mut self, out: &mut AdapterOutput<Self::Response>)
fn finish(&mut self, out: &mut AdapterOutput<Self::Response>)
End-of-stream flush on EOF without a terminal (close open blocks).
Never runs after a transport error (truncation drops partials) or after
a terminal was interpreted. Must not synthesize a terminal record: EOF
without the provider’s own end event is truncation, and a fabricated
terminal would read as a successfully completed turn. (A terminal the
provider did signal earlier — e.g. the chat-completions [DONE]
sentinel or a finish_reason chunk, whose usage trailer arrives later —
may be emitted here; that is deferral, not synthesis.)
Provided Methods§
Sourcefn flush_before_terminal_error(
&mut self,
_out: &mut AdapterOutput<Self::Response>,
)
fn flush_before_terminal_error( &mut self, _out: &mut AdapterOutput<Self::Response>, )
Flush content the provider fully delivered before a terminal error item (a transport failure or an in-band provider error envelope) reaches the consumer.
Default: nothing — truncation drops partials. Wires that buffer
fully-delivered tool calls (the chat-completions compat family, the
Responses SSE loop) override this so a first-Err-stop consumer still
sees them. Must not push a terminal record.
Sourcefn is_finished(&self) -> bool
fn is_finished(&self) -> bool
Whether interpret consumed the wire’s own in-band terminal failure.
When true after an interpret call, the driver stops consuming without
running the EOF finish flush — the adapter has already pushed the
flush-then-Err sequence itself. Default: never.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".