ai.wire.sanitize_for_client

Make one run's journal safe to replay to a client of `provider` asking for `requested_model`, and return the sanitized copy. Every client should lower `ai.wire.sanitize_for_client(input.journal, provider, self.requested_model())` instead of `input.journal`. The rules, in the order they apply per event:

Reference version

Signature

function ai.wire.sanitize_for_client(
provider: string,
requested_model: string
) -> ai.Journal throws never

Make one run's journal safe to replay to a client of provider asking for requested_model, and return the sanitized copy. Every client should lower ai.wire.sanitize_for_client(input.journal, provider, self.requested_model()) instead of input.journal. The rules, in the order they apply per event:

  1. An assistant turn from a DIFFERENT provider or requested model loses its ai.content.Reasoning blocks: one model's thinking is not replayable to another (and providers that check reasoning signatures reject it).
  2. Empty and whitespace-only ai.content.Text blocks are dropped from assistant turns.
  3. An assistant turn left with no blocks at all is dropped entirely — the reasoning-only turn that lowers to content: [] and makes Anthropic 400, and the same shape an aborted turn leaves behind. Such a turn never has tool calls, so nothing is orphaned by dropping it.
  4. A tool call with no ToolCompleted/ToolFailed before the next assistant or user message (or before the end of the journal) gets a synthesized ToolFailed { message: "No result provided" }, because most APIs reject a tool call that was never answered.

Journal-only events (RunStarted, ToolRequested, FinalProduced) pass through untouched — clients skip them anyway — and, like the clients' own lowering, they never close an open tool-result group. Nothing here mutates the journal it is given.

Source:<builtin>/ai/ns_wire/wire.bamlbytes 28356–30540