OpenPay (1 crate, 2174 LOC, 14 tests)
op-payouts Multi-rail payout engine. Visa Direct, Mastercard Send,
ACH credits (NACHA), Fedwire + SWIFT MT103 + ISO 20022
pacs.008, SEPA SCT + SCT Inst (mod-97 IBAN), UK FPS,
FedNow, RTP, PayPal, Wise. Crypto: USDC/USDT on
ETH/Polygon/Base/Solana + BTC + Lightning with real
ERC-20 transfer(address,uint256) calldata. Offline-pure
drivers (emit wire payloads — operators transmit).
Smart Byte (1 crate, 2605 LOC, 38 tests)
smart-byte-nostr Nostr adapter. NIP-01 canonical event id + BIP-340
Schnorr sign/verify; from-scratch bech32 + NIP-19 TLV
(npub/nsec/note/nprofile/nevent/nrelay); NIP-04 legacy
AES-256-CBC DMs; NIP-44 v2 HKDF-SHA256→ChaCha20+HMAC
with bucketed padding; NIP-17 gift-wrap (kind 1059) +
seal (kind 13) + rumor (kind 14); NIP-05/11/13/26/65.
Relay client message vocabulary (REQ/EVENT/CLOSE/AUTH/
EOSE/OK/NOTICE/CLOSED) + in-memory router.
EOC (1 crate, 2024 LOC, 30 tests)
eoc-streaming Token-by-token + tool-call streaming primitives.
SSE framing (data: lines); Anthropic event mapper
(message_start/content_block_*/message_delta/stop/ping);
OpenAI delta mapper; Vercel AI SDK mapper. Bounded-channel
backpressure with watermarks; CancelToken propagation;
Last-Event-ID resumable streams; per-stream joule meter.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
98 lines
2.7 KiB
Rust
98 lines
2.7 KiB
Rust
//! WebSocket framing helpers.
|
|
//!
|
|
//! This module deliberately does **not** speak the WebSocket wire
|
|
//! protocol — that lives in `tokio-tungstenite` and similar crates and
|
|
//! is out of scope for an EOC primitive. What we do provide is the
|
|
//! transport-agnostic message vocabulary the host bridge translates
|
|
//! into real WS frames, plus utilities to serialize a streaming
|
|
//! [`crate::stream::Event`] as a WS text payload.
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::error::StreamResult;
|
|
use crate::stream::Event;
|
|
|
|
/// WebSocket opcode subset relevant to streaming inference.
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
|
#[serde(rename_all = "lowercase")]
|
|
pub enum WsOpcode {
|
|
/// UTF-8 JSON payload.
|
|
Text,
|
|
/// Binary payload (e.g. tool-result bytes).
|
|
Binary,
|
|
/// Liveness ping (host bridge should reply with `Pong`).
|
|
Ping,
|
|
/// Liveness pong.
|
|
Pong,
|
|
/// Connection close.
|
|
Close,
|
|
}
|
|
|
|
/// A WebSocket frame as carried through the EOC streaming layer.
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct WsFrame {
|
|
/// Opcode.
|
|
pub opcode: WsOpcode,
|
|
/// Payload bytes. For `Text` frames the bytes are UTF-8 JSON.
|
|
pub payload: Vec<u8>,
|
|
}
|
|
|
|
impl WsFrame {
|
|
/// Construct a text JSON frame from a normalized [`Event`].
|
|
pub fn text_event(event: &Event) -> StreamResult<Self> {
|
|
let bytes = serde_json::to_vec(event)?;
|
|
Ok(Self {
|
|
opcode: WsOpcode::Text,
|
|
payload: bytes,
|
|
})
|
|
}
|
|
|
|
/// Construct a ping frame with an optional payload (echo data).
|
|
pub fn ping(payload: Vec<u8>) -> Self {
|
|
Self {
|
|
opcode: WsOpcode::Ping,
|
|
payload,
|
|
}
|
|
}
|
|
|
|
/// Construct a pong frame echoing a ping's payload.
|
|
pub fn pong(payload: Vec<u8>) -> Self {
|
|
Self {
|
|
opcode: WsOpcode::Pong,
|
|
payload,
|
|
}
|
|
}
|
|
|
|
/// Construct a close frame.
|
|
pub fn close() -> Self {
|
|
Self {
|
|
opcode: WsOpcode::Close,
|
|
payload: Vec::new(),
|
|
}
|
|
}
|
|
|
|
/// Decode a text frame back into an [`Event`].
|
|
pub fn decode_event(&self) -> StreamResult<Event> {
|
|
let s = std::str::from_utf8(&self.payload)
|
|
.map_err(|e| crate::error::StreamError::Framing(e.to_string()))?;
|
|
Ok(serde_json::from_str(s)?)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::stream::Role;
|
|
|
|
#[test]
|
|
fn roundtrip_text_event() {
|
|
let e = Event::MessageStart {
|
|
id: Some("m".into()),
|
|
role: Role::Assistant,
|
|
};
|
|
let frame = WsFrame::text_event(&e).unwrap();
|
|
assert_eq!(frame.opcode, WsOpcode::Text);
|
|
let decoded = frame.decode_event().unwrap();
|
|
assert_eq!(decoded, e);
|
|
}
|
|
}
|