Message
Shows one turn of a run's thread.
From
Agent
Wrote 1,204 partitions.- Read sourceRead sourcelake://events/2026-10-181.2sDoneDone
- Write partitionsWrite partitionswh_events.events_raw14sDoneDone
Wrote 1,204 partitions to
wh_events.events_raw. Three arrived after the 02:00 cutoff:2026-10-18/14,/15and/22.agentdefault
- Run 4812 started
Mira
Backfill yesterday's partitions for eu-west-2 and tell me which ones were late.person
States
Agent
Writing partitions to
wh_events.events_raw.done
Agent
WorkingWriting partitions to
wh_events.events_raw.working
Agent
Waiting on youWriting partitions to
wh_events.events_raw.waiting
Agent
FailedThe write stopped at partition 812: the role
etl_writerlacks INSERT onevents_raw.failed
Agent
StoppedWriting partitions to
wh_events.events_raw.stopped
Mira
SendingBackfill yesterday's partitions for eu-west-2 and tell me which ones were late.sending
Mira
Not sentBackfill yesterday's partitions for eu-west-2 and tell me which ones were late.not sent
Usage
When to use it
- Use
- A person and an agent take turns on a run: an instruction, then the steps and the answer.
- Use
- A log of what was asked and done on a pipeline, read top to bottom.
- Not for
- The steps alone, with no one asking. Use Tool-call row.
- Not for
- One line of what the run is doing. Use Activity.
Rules
7 rules
- Must
- Put the turns in a MessageGroup, in order, on the page or in message flow; never in a frame. Because turns are divided by faint rules, and a ToolCallList inside a turn draws boxes that would sit in a box.
- Must
- Order an agent's turn as Activity, then ToolCallList, then Response, leaving out what it does not have. Because the person reads what it is doing, then what it did, then what it says, in every turn.
- Must
- Pass state for a turn that is working, waiting, failed or stopped; leave it out when the turn is done. Because the word in the label column is how a scan finds the turn that needs the person, and done is the normal end.
- Never
- Wrap a person's words in a bubble, a box or a fill. Because Sodium reads a thread as a log, and the > before their words already says who wrote them.
- Must
- Keep a person's turn that did not send, with state="not-sent" and onRetry. Because their words stay where they wrote them, Not sent says what happened and Retry is the way on.
- Should
- Put an agent turn's actions in footer as ghost buttons: copy, replay. Because the thread is read, not acted on, and the composer below holds the one primary.
- Should
- Mark a point in the thread with MessageDivider and a short name ("Run 4812 started"). Because a rule with a micro label splits the log where something changed, without a turn of its own.
Accessibility
3 checks
- Each turn is an article with its name as a heading, so a screen reader can move turn by turn.
- The state is a word, never only a colour; the pending mark and the > are aria-hidden.
- A working or sending turn sets aria-busy.
Edge cases
4 edge cases
- Narrow turn
- Under 512px wide the label column folds into one line above the turn, by the turn's own width.
- Long unbroken text
- Breaks inside the word rather than widening the thread.
- Line breaks in a person's words
- Kept as they wrote them.
- Long name
- Truncates in the label column.
API
8 props
from'agent' | 'person'default'agent'namestringdefaultrequiredtimeReactNodestate'done' | 'running' | 'waiting' | 'failed' | 'stopped' | 'sending' | 'not-sent'default'done'footerReactNodeonRetry() => voidlabelsMessageLabelsdefaultEnglishMessageGroup, MessageDividerdiv
Tokens
14 tokens
--label-col- 160px
--line-faint- #efede6
--line- #e2dfd5
--text-1- #161512
--text-2- #55524a
--text-3- #6b675e
--warn-text- #a14b00
--fail-text- #b3261e
--type-label-sm- 400 12px/16px var(--font-mono)
--type-code-sm- 400 12px/16px var(--font-mono)
--type-code- 400 13px/20px var(--font-mono)
--type-body- 400 15px/24px var(--font-sans)
--type-micro- 400 11px/14px var(--font-mono)
--pending-cell- 3px