← All Problems

5. Per-Context Chunk Sequencing for Multiplexed Streams

Confirmed Medium Grouping / Sort
Grounding: Confirmed: a single Cartesia WebSocket connection supports multiple independent "contexts," each a full-duplex continuous stream; a "continuation" uses a context_id to group streamed word chunks into one continuous utterance, and each new chunk is appended to that context's prior history so prosody stays continuous without reprocessing the whole transcript (Source: docs.cartesia.ai/get-started/realtime-text-to-speech-quickstart).

Problem

Several independent utterances can be streaming over the same connection at once, each identified by a context id. Text chunks for different contexts can arrive interleaved with each other, and even within one context a chunk can technically be delivered out of its own sequence order.

Before any of it is usable, each context's chunks need to be regrouped and put back in order. Given the raw arrival stream, reassemble each context's full text.

Source: src/5_context_chunk_sequencer.py

def sequence_contexts(events: list[tuple[str, int, str]]) -> dict[str, str]:
    ...

Examples:
>>> sequence_contexts([("a", 1, "world"), ("b", 0, "Hi "), ("a", 0, "Hello "), ("b", 1, "there")])
{"a": "Hello world", "b": "Hi there"}

>>> sequence_contexts([("x", 2, "C"), ("x", 0, "A"), ("x", 1, "B")])
{"x": "ABC"}

Step-by-Step Approach

  1. Make one pass over events in arrival order and bucket each (seq, text) pair into a dict keyed by context_id, using setdefault to lazily create each context's list.
  2. Arrival order across and within contexts is irrelevant at this stage — grouping alone is enough to separate the interleaved stream back into per-context sub-streams.
  3. For each context's list, sort by seq. This is the step that undoes any out-of-order delivery within a single context.
  4. Concatenate the sorted list's text pieces in order to get that context's fully reassembled string.
  5. Build the result dict as context_id -> reassembled_text and return it; an empty events list naturally produces an empty dict with no special-casing needed.

The key insight is that this is a two-phase group-then-sort, not a single streaming pass: chunk ordering only makes sense within one context, so contexts have to be separated first before per-context order can be reconstructed.

Reference solution

def sequence_contexts(events: list[tuple[str, int, str]]) -> dict[str, str]:
    # group each context's (seq, text) pairs together, preserving arrival order for now
    groups: dict[str, list[tuple[int, str]]] = {}
    for context_id, seq, text in events:
        groups.setdefault(context_id, []).append((seq, text))
    result: dict[str, str] = {}
    for context_id, pieces in groups.items():
        # sort by seq to undo any out-of-order delivery within the context
        pieces.sort(key=lambda p: p[0])
        result[context_id] = "".join(text for _, text in pieces)
    return result

Key Functions & Tricks

  • dict.setdefault(context_id, []) — lazily creates each context's bucket on first sight, avoiding a separate existence check.
  • pieces.sort(key=lambda p: p[0]) — sorts each context's chunks by seq independently of every other context.
  • "".join(text for _, text in pieces) — concatenates in O(n) rather than repeated string concatenation in a loop.
  • Group-then-sort — the general pattern for reconstructing multiple independent ordered sequences from one interleaved stream.

How to Recognize This Pattern

The signal is "one interleaved stream actually contains several independent ordered sub-streams, tagged by a key" — multiplexed connections, multi-tenant logs, or any fan-in of several producers onto one channel have this shape. The fix is almost always group-by-key, then sort-or-merge within each group; resist the urge to try to reconstruct order in a single pass over the raw stream, since a chunk's neighbors in arrival order usually aren't its neighbors in sequence order. A common variation adds a finalize/close event per context and asks you to detect when a context is fully complete (all seqs 0..final present) rather than just reassembling whatever arrived. A common pitfall is concatenating text pieces before sorting, which silently produces a wrong-but-plausible-looking string instead of an obvious error.