SDK Overview
Diminuendo ships with four official client SDKs — TypeScript, Rust, Python, and Swift — each providing a typed, ergonomic interface to the full 21-message, 51-event wire protocol. The SDKs are designed to be standalone: they carry no gateway-specific dependencies and communicate exclusively over standard WebSocket connections using JSON framing. Any WebSocket-capable runtime can use them.Design Principles
All four SDKs share a common set of design principles, despite their divergent language idioms:Full Protocol Parity
Every client message type and every server event type is represented in each SDK. No event is silently dropped. No message type is missing. The SDKs are functionally equivalent — anything one can do, all can do.
Zero Gateway Dependencies
The SDKs do not import gateway code, do not share types via monorepo packages, and do not require code generation. Each SDK defines its own types from the wire protocol specification. This ensures they can be published and used independently.
Native Idioms
TypeScript uses Promises and typed event handlers. Rust uses async channels and serde. Python uses asyncio and dataclasses. Swift uses async/await and Codable. Each SDK feels native to its language — no lowest-common-denominator abstraction.
Adversarial Test Suites
Every SDK has a comprehensive test suite that does not merely verify happy paths, but actively attempts to break the client with malformed data, concurrent operations, timeouts, and edge cases. See Testing Methodology for details.
SDK Comparison
| Aspect | TypeScript | Rust | Python | Swift |
|---|---|---|---|---|
| Runtime | Node.js, Bun, Deno, browsers | tokio (async runtime) | asyncio + websockets | Swift Concurrency + URLSessionWebSocketTask |
| Dependencies | Zero runtime deps | tokio, serde, tokio-tungstenite, futures-util, thiserror, tracing | websockets | None (Foundation only) |
| Async Model | Promises + event callbacks | mpsc::UnboundedReceiver<ServerEvent> | async/await + event callbacks | async/await + AsyncStream<ServerEvent> |
| Type System | TypeScript interfaces (compile-time) | Rust enums with #[serde(tag = "type")] (compile + runtime) | Dataclasses with from_dict parsers | Codable enums/structs with CodingKeys |
| Event Delivery | .on(type, handler) with unsubscribe | Channel-based (events.recv().await) | .on(type, handler) with unsubscribe | AsyncStream consumption in a for await loop |
| Wildcard Events | .on("*", handler) | ServerEvent::Unknown catch-all | .on("*", handler) | .unknown catch-all case |
| Wire Mapping | camelCase (native) | #[serde(rename)] from snake_case | from_dict with explicit key mapping | CodingKeys with camelCase |
| Connection Management | Auto-reconnect, ping timer | Manual (application controls lifecycle) | Auto-reconnect, ping timer | Auto-reconnect, ping timer |
| Primary Use Case | Web apps, Node.js services | Tauri desktop apps, CLI tools | Scripts, testing, notebooks | macOS/iOS apps, SwiftUI clients |
| Test Count | 137 tests | 178 tests | 173 tests | 193 tests |
TypeScript SDK
The TypeScript SDK (sdk/typescript/) is a zero-dependency WebSocket client that works in any JavaScript runtime with a standard WebSocket global — browsers, Node.js 21+, Bun, and Deno. It provides a Promise-based API for request-response operations and typed event handlers for streaming events.
- Auto-reconnect: Configurable via
autoReconnectandreconnectDelayoptions. On disconnect, the client automatically re-establishes the connection and re-authenticates. - Ping keepalive: Sends periodic pings (default 30s) to detect stale connections. The
ping()method returns latency in milliseconds. - Request chaining: Concurrent requests of the same type to the same session are serialized internally to prevent response mismatching.
- Typed
on(): The event handler’s parameter type is narrowed to the specific event type, providing full IntelliSense and compile-time safety.
TypeScript SDK Reference
Full API documentation, installation, and usage examples.
Rust SDK
The Rust SDK (sdk/rust/) is an async WebSocket client built on tokio, designed primarily for Tauri v2 desktop applications and CLI tools. It uses an mpsc channel pair for event delivery — the client sends messages via methods on DiminuendoClient, and events arrive on an UnboundedReceiver<ServerEvent>.
- Send + Sync: The client is safe to share across Tauri command handlers and tokio tasks. All operations are non-blocking.
- Serde-based types: All 21
ClientMessagevariants and 51ServerEventvariants deriveSerialize/Deserializewith exact camelCase wire mapping via#[serde(rename)]. - Unknown variant: The
ServerEventenum includes#[serde(other)] Unknown, so future event types added to the protocol do not cause deserialization failures. - Background I/O: A spawned tokio task handles all WebSocket reads and writes, decoupling the application from I/O scheduling.
Rust SDK Reference
Full API documentation, Cargo setup, and Tauri integration guide.
Python SDK
The Python SDK (sdk/python/) is an asyncio-based WebSocket client using the websockets library. It provides a callback-based event model with wildcard support, and dataclass-based types with from_dict class methods for parsing wire data.
- Dataclass types:
SessionMeta,FileEntry,IterationMeta,FileContent,StateSnapshot, andHistoryItemare@dataclasstypes withfrom_dictclass methods that handle the camelCase-to-snake_case mapping. - ServerEvent wrapper: All events are wrapped in a
ServerEventdataclass with convenience properties:session_id,turn_id,text,final_text,error_code,error_message,seq,ts, and category checks likeis_turn_event,is_tool_event,is_thinking_event. - Auto-reconnect: Configurable via
auto_reconnectandreconnect_delayoptions. - Predicate-based requests: Internal request/response matching uses predicates, allowing the client to wait for specific response types without blocking other event processing.
Python SDK Reference
Full API documentation, pip installation, and usage examples.
Swift SDK
The Swift SDK (sdk/swift/) is an actor-based client built on Swift Concurrency and URLSessionWebSocketTask. It delivers events through an AsyncStream<ServerEvent> and uses Codable for all 21 client messages and 51 server events. It has zero third-party dependencies.
- Actor-based concurrency: The client is a Swift
actor, providing inherent thread safety for all mutable state. All public types areSendable. - AsyncStream event delivery: Events arrive via
AsyncStream<ServerEvent>for idiomaticfor awaitloops in SwiftUI views or background tasks. - Zero third-party dependencies: Uses only Foundation’s
URLSessionWebSocketTaskfor WebSocket communication. - Auto-reconnect and ping keepalive: Configurable via
ClientOptions, matching the behavior of the TypeScript and Python SDKs.
Swift SDK Reference
Full API documentation, Swift Package Manager setup, and macOS/iOS guidance.
Protocol Coverage Matrix
Every client message and server event is implemented in all four SDKs. The following table confirms full parity:21 Client Messages
21 Client Messages
| Message Type | TypeScript | Rust | Python | Swift |
|---|---|---|---|---|
authenticate | Yes | Yes | Yes | Yes |
list_sessions | Yes | Yes | Yes | Yes |
create_session | Yes | Yes | Yes | Yes |
rename_session | Yes | Yes | Yes | Yes |
archive_session | Yes | Yes | Yes | Yes |
unarchive_session | Yes | Yes | Yes | Yes |
delete_session | Yes | Yes | Yes | Yes |
join_session | Yes | Yes | Yes | Yes |
leave_session | Yes | Yes | Yes | Yes |
run_turn | Yes | Yes | Yes | Yes |
stop_turn | Yes | Yes | Yes | Yes |
steer | Yes | Yes | Yes | Yes |
answer_question | Yes | Yes | Yes | Yes |
get_history | Yes | Yes | Yes | Yes |
get_events | Yes | Yes | Yes | Yes |
ping | Yes | Yes | Yes | Yes |
list_files | Yes | Yes | Yes | Yes |
read_file | Yes | Yes | Yes | Yes |
file_history | Yes | Yes | Yes | Yes |
file_at_iteration | Yes | Yes | Yes | Yes |
manage_members | Yes | Yes | Yes | Yes |
51 Server Events
51 Server Events
| Event Type | TypeScript | Rust | Python | Swift |
|---|---|---|---|---|
welcome | Yes | Yes | Yes | Yes |
connected | Yes | Yes | Yes | Yes |
authenticated | Yes | Yes | Yes | Yes |
heartbeat | Yes | Yes | Yes | Yes |
session_list | Yes | Yes | Yes | Yes |
session_created | Yes | Yes | Yes | Yes |
session_updated | Yes | Yes | Yes | Yes |
session_archived | Yes | Yes | Yes | Yes |
session_unarchived | Yes | Yes | Yes | Yes |
session_deleted | Yes | Yes | Yes | Yes |
session_state | Yes | Yes | Yes | Yes |
state_snapshot | Yes | Yes | Yes | Yes |
stream_snapshot | Yes | Yes | Yes | Yes |
turn_started | Yes | Yes | Yes | Yes |
text_delta | Yes | Yes | Yes | Yes |
turn_complete | Yes | Yes | Yes | Yes |
turn_error | Yes | Yes | Yes | Yes |
message.delta | Yes | Yes | Yes | Yes |
message.complete | Yes | Yes | Yes | Yes |
tool_call | Yes | Yes | Yes | Yes |
tool_result | Yes | Yes | Yes | Yes |
tool_call_start | Yes | Yes | Yes | Yes |
tool_call_delta | Yes | Yes | Yes | Yes |
tool_error | Yes | Yes | Yes | Yes |
question_requested | Yes | Yes | Yes | Yes |
permission_requested | Yes | Yes | Yes | Yes |
approval_resolved | Yes | Yes | Yes | Yes |
thinking_start | Yes | Yes | Yes | Yes |
thinking_progress | Yes | Yes | Yes | Yes |
thinking_complete | Yes | Yes | Yes | Yes |
terminal_stream | Yes | Yes | Yes | Yes |
terminal_complete | Yes | Yes | Yes | Yes |
sandbox_init | Yes | Yes | Yes | Yes |
sandbox_provisioning | Yes | Yes | Yes | Yes |
sandbox_ready | Yes | Yes | Yes | Yes |
sandbox_removed | Yes | Yes | Yes | Yes |
usage_update | Yes | Yes | Yes | Yes |
usage_context | Yes | Yes | Yes | Yes |
gap | Yes | Yes | Yes | Yes |
replay_complete | Yes | Yes | Yes | Yes |
file_list | Yes | Yes | Yes | Yes |
file_content | Yes | Yes | Yes | Yes |
file_history_result | Yes | Yes | Yes | Yes |
file_changed | Yes | Yes | Yes | Yes |
steer_sent | Yes | Yes | Yes | Yes |
stop_acknowledged | Yes | Yes | Yes | Yes |
server_shutdown | Yes | Yes | Yes | Yes |
history | Yes | Yes | Yes | Yes |
events | Yes | Yes | Yes | Yes |
member_list | Yes | Yes | Yes | Yes |
member_updated | Yes | Yes | Yes | Yes |
member_removed | Yes | Yes | Yes | Yes |
error | Yes | Yes | Yes | Yes |
pong | Yes | Yes | Yes | Yes |
Testing
The SDKs collectively include 681 tests and approximately 3,100 assertions, covering every message type, every event type, every error code, and a range of adversarial edge cases. With the gateway’s 9 integration tests, the repository totals 690 tests. The testing methodology follows a Popperian epistemology — tests are designed to refute, not confirm, and confidence comes from the failure to find bugs despite aggressive attempts.Testing Methodology
Detailed explanation of the adversarial testing approach, test architecture per SDK, and what makes the test suites severe.
Running the Tests
Coverage Statistics
| SDK | Tests | Assertions | Message Types | Event Types | Error Types |
|---|---|---|---|---|---|
| TypeScript | 137 | ~600 | 21/21 | 51/51 | All |
| Rust | 178 | ~800 | 21/21 | 51/51 | All |
| Python | 173 | ~800 | 21/21 | 51/51 | All |
| Swift | 193 | ~900 | 21/21 | 51/51 | All |
| Total (SDKs) | 681 | ~3,100 | 21/21 | 51/51 | All |