openai.internal.chat_lower_journal
`ai.Journal` -> chat-completions messages. Assistant turns carry their text in `content` and their calls in `tool_calls`; each result comes back as its own `role: "tool"` message keyed by `tool_call_id`. Journal-only events (`RunStarted`, `ToolRequested`, `Usage`, `FinalProduced`) and reasoning blocks lower to nothing.
Signature
ai.Journal -> chat-completions messages. Assistant turns carry their text
in content and their calls in tool_calls; each result comes back as its
own role: "tool" message keyed by tool_call_id. Journal-only events
(RunStarted, ToolRequested, Usage, FinalProduced) and reasoning
blocks lower to nothing.
Callers pass the journal through ai.wire.sanitize_for_client first, so
foreign reasoning, empty turns and unanswered tool calls are already handled.
A journal turn's text always collapses to a bare string (_chat_content
with collapse = true): a text-only turn was always sent that way, and a
bare string is the one content shape every compatible server accepts. A
turn carrying media, or a user turn carrying metadata, is a part list.
Source:<builtin>/openai/ns_internal/chat.bamlbytes 28984–32897