Implement ratatoskr.sse_client — SSE consumer, reconnect, cancel #1
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Ratatoskr needs a Python SSE consumer module for the Worldtree Conversation API. This module is the integration seam between Ratatoskr (separate-repo, separate-team, spec-only-consumer) and Worldtree — every higher feature (Textual TUI,
--sendnon-interactive mode, two-stage Ctrl-C, scripted CI probes) lands on top of it.The Worldtree spec emits SSE events with a composite
{turn_id}:{seq}id:wire field (spec INV-014) that is load-bearing for:POST /sessions/{id}/turns/{turn_id}/cancel—turn_idis parsed from the SSE wireid:).Last-Event-IDHTTP header.turn_idprefix).Hand-rolled
data:-only SSE parsing (the skaldsong pattern) silently drops theid:line and breaks both flows invisibly.docs/design-brief.md§3 names this as the foot-gun this module must close.Solution
Implement
src/ratatoskr/sse_client.pyper the contract atdocs/contracts/issues/1.contract.md. The contract specifies four functions and the typedEventenvelope:stream_turn(client, session_id, content) -> AsyncIterator[Event]— POST a user message and consume the SSE response stream.reconnect_turn(client, session_id, last_event_id) -> AsyncIterator[Event]— re-attach to an in-flight turn viaLast-Event-ID.cancel_turn(client, session_id, turn_id, *, persist_partial=False) -> CancelResult— server-side cancel._parse_sse_id(raw) -> SseId— strict parser for the composite wireid:field.Hard invariants (per contract):
Eventcarries a parsedSseId(turn_id, seq)— impossible to silently drop theid:line.turn_idis stable across events; a mid-stream flip raisesTurnIdFlip.core.*/worldtree.*imports (boundary already enforced bytests/test_no_worldtree_imports.py).TDD via tracer tests per function block. Recommended vertical slice:
_parse_sse_id→stream_turn→reconnect_turn→cancel_turn. Each function's first listed test (tagged[..,tracer]) is the RED test for that function; remaining tests follow one at a time per thetddskill.Benefits
docs/design-brief.md§3 names (silentid:drop).--sendstdout) — neither forks the SSE parsing.cancel_turnis GREEN.Acceptance
uv run pytest tests/).tests/test_no_worldtree_imports.pycontinues to pass.tests/snapshots/README.md); fixture recording can land in a follow-up issue.docs/SPEC-PIN.md) unchanged; this module is built against Worldtree v0.19.0 / repo SHA55101e909abcd2219833266b6f905c5bc956e0f0.Dependencies
None. This is the first module in the dependency graph — every other module imports
Eventand/or invokes the three entry points.Closed — shipped. ratatoskr.sse_client implemented via TDD (commit
02f2a04, Volva-reviewed inc17af18). Live against personal Worldtree since v0 milestone.