@startuml !theme plain title Turnstone — Client SDK Architecture skinparam class { BackgroundColor<> #C8E6C9 BackgroundColor<> #B8D4E3 BackgroundColor<> #FFE0B2 BackgroundColor<> #F0F4C3 BackgroundColor<> #E1BEE7 } skinparam packageBorderColor #888888 skinparam ArrowColor #555555 ' Python SDK package "turnstone/sdk/ (Python)" { abstract class _BaseClient <> { - _client: httpx.AsyncClient - _owns_client: bool + _request(method, path, ...) → T + _stream_sse(path, ...) → AsyncIterator + aclose() } class AsyncTurnstoneServer <> { + list_workstreams() + dashboard() + create_workstream() + close_workstream() + send(message, ws_id) + approve() + command() + cancel(ws_id) + stream_events(ws_id) + stream_global_events() + send_and_wait() + list_saved_workstreams() + login() / logout() + health() } class AsyncTurnstoneConsole <> { + overview() + nodes() + workstreams() + node_detail() + snapshot() + create_workstream() + stream_cluster_events() + login() / logout() + health() } class TurnstoneServer <> { - _async: AsyncTurnstoneServer - _runner: _SyncRunner .. delegates all methods .. + __enter__ / __exit__ } class TurnstoneConsole <> { - _async: AsyncTurnstoneConsole - _runner: _SyncRunner .. delegates all methods .. + __enter__ / __exit__ } class _SyncRunner <> { - _loop: EventLoop - _thread: Thread + run(coro) → T + run_iter(async_gen) → Iterator + close() } class TurnResult <> { + ws_id: str + content_parts: list[str] + reasoning_parts: list[str] + tool_results: list + errors: list[str] + timed_out: bool -- + content: str + reasoning: str + ok: bool } class ServerEvent <> { + type: str + ws_id: str + from_dict() → ServerEvent } class ClusterEvent <> { + type: str + from_dict() → ClusterEvent } _BaseClient <|-- AsyncTurnstoneServer _BaseClient <|-- AsyncTurnstoneConsole TurnstoneServer --> AsyncTurnstoneServer : wraps TurnstoneServer --> _SyncRunner : uses TurnstoneConsole --> AsyncTurnstoneConsole : wraps TurnstoneConsole --> _SyncRunner : uses AsyncTurnstoneServer ..> TurnResult : returns AsyncTurnstoneServer ..> ServerEvent : yields AsyncTurnstoneConsole ..> ClusterEvent : yields } ' TypeScript SDK package "sdk/typescript/ (TypeScript)" { class "BaseClient" as TSBase <> { # baseUrl: string # token: string # fetchFn: fetch # request() # streamSSE() } class "TurnstoneServer" as TSServer <> { + listWorkstreams() + send() + streamEvents() + sendAndWait() ... } class "TurnstoneConsole" as TSConsole <> { + overview() + nodes() + snapshot() + clusterEvents() ... } TSBase <|-- TSServer TSBase <|-- TSConsole } ' External connections class "turnstone-server :8080" as Server <> class "turnstone-console :8081" as Console <> AsyncTurnstoneServer --> Server : httpx REST + SSE AsyncTurnstoneConsole --> Console : httpx REST + SSE TSServer --> Server : fetch REST + SSE TSConsole --> Console : fetch REST + SSE note right of AsyncTurnstoneServer Returns Pydantic models from turnstone.api.server_schemas (no type duplication) end note @enduml