Read first: Message Based Communication. A plain hub.Observe(request, …) waits for exactly ONE reply. This page is the other shape: a reply that arrives in parts.

Why

The model relay (MeshWeaver.Plugins Hosting/ModelRelay) runs a language model on a person's own machine. The machine answers over its participant connection, and a chat completion is a stream of tokens that may take minutes. One reply at the end would make the reader wait for the whole answer, and a total-duration bound would cut a long answer that is still arriving. The mesh's request/response contract had one terminal reply per request (an AsyncSubject), with RequestProgress as the only non-terminal message — and progress carries no payload.

The contract

// Caller — cold: the request is posted on Subscribe.
hub.ObserveStreamed(new MyRequest(…), o => o.WithTarget(address))
   .Subscribe(delivery =>
   {
       if (delivery.IsResponsePart()) Append((MyPart)delivery.Message);
       else Finish((MyReply)delivery.Message);          // the terminal reply, emitted last
   }, error => …);                                       // DeliveryFailureException / TimeoutException

// Handler
.WithHandler<MyRequest>((hub, request) =>
{
    if (!request.AcceptsResponseParts())                 // a single-reply caller: answer ONCE
    {
        hub.Post(WholeReply(), o => o.ResponseFor(request));
        return request.Processed();
    }
    var n = 0L;
    produce.Subscribe(
        part => hub.PostResponsePart(request, part, n++),
        error => hub.Post(new DeliveryFailure(…), o => o.ResponseFor(request)),
        () => hub.PostFinalResponse(request, new MyReply(…), n));
    return request.Processed();
});
Piece What it does
PostOptions.AcceptsResponseParts Stamped by ObserveStreamed on the request. A handler sends parts only to a request that carries it, so a caller that predates the feature (an older image during a roll) is never sent a part it would take for its reply.
PostOptions.ResponsePart The part's zero-based number. A part is correlated like the reply (RequestId), never consumes the callback, and restarts the request's silence deadline.
PostOptions.ResponsePartCount On the terminal reply: how many parts came before it. The stream completes only once that many parts were emitted, so a part that arrives after the reply is still delivered, in order.

The rules it keeps

Not built

Pinned by StreamedResponseTest (MeshWeaver.Messaging.Hub.Test): parts in order then the reply, parts posted in reverse re-ordered, a single-reply caller answered once and never sent a part, and a stream that goes quiet before its reply timed out after the parts that did arrive.