5c595b862d
The Starlette endpoints (create / stream / cancel / tools / messages) now go through ratatoskr.wt over the worldtree-sdk; the browser contract is preserved. This is the last consumer of the hand-rolled turn-stream family — after this, stream_turn* / cancel_turn are orphaned and get deleted in part 2b-iii (with the live smoke). - _wt_client wraps a client_factory transport as the adapter's WorldtreeClient (INV-CUT-1), reading base_url + bearer off the transport (a no-auth test transport falls back to a placeholder key). The hand-rolled endpoints (persona / agents / admin / bifrost) keep using the raw transport until their slices. - _event_to_browser_payload derives the browser payload from the SDK's `raw` (the wire body) minus the redundant `type`, plus the composite `sse_id` string — the SAME shape the old dataclasses produced, so the presentation fixture + browser JS are unchanged; the browser event_type is the wire `type`, not the SDK class name. - The stream endpoint captures the upstream cancel target from the composite sse_id (the SDK's top-level turn_id is body-derived, absent on text frames); create reads the SDK's open create dict; cancel reads CancelResult.cancelled and surfaces a generic 502 for CancelFailed (the SDK abstracts the upstream cancel HTTP status). - test_web_presentation_contract builds SDK events via build_event; two cancel tests adopt the SDK's (status, error_code) race pairs + the 502. Suite 570 green; web/server.py + presentation test ruff-clean, mypy unchanged (same pre-existing errors). Patch (internal; browser contract preserved).