Chat Message
AI · ChatMessage
One turn in a conversation with an agent: user bubble on the right, agent reply as rich text on the left.
Props: role ("user" | "assistant" | "system"), name, time, model, text (Markdown subset: paragraphs, bold, code, - lists, 1. lists, ### headings, links,
code blocks), `streaming` (blinking caret, no actions yet), `tint` (agent color), `sources` ({title, icon, url | onClick}), `attachments` ({name, size}), `usage` (tokens · cost text), `onRetry`, `onFeedback("up" | "down")`, `actions` (false hides the row), `before` / `after` (slots for tool calls, reasoning, approvals).
- User messages are ink pills, agent replies are plain text on the surface: the agent's words get the space.
- Actions (copy, regenerate, thumbs) appear once streaming ends.
- Number sources in the order they were used; keep titles short.
- `RichText` and `CodeBlock` are exported on their own for docs, notes and logs.
ME
Which invoices are overdue? Fix the reminder job too.
reminders.ts4 KB
Three invoices are overdue, €2,520 in total:
- #2041 Harbor & Co · €860
- #2058 Pinegate · €1,240
- #2063 Orbit Foods · €420
The fix for the reminder job:
ts
const due = invoices.filter(i => i.dueAt < now && !i.paid);
await sendReminders(due, { tone: "friendly" });
1,842 tokens · €0.01
Ledger switched to Claude Haiku 5.5
Sending reminders now. Harbor & Co first because
Props
ChatMessage
| Prop | Type | Notes |
|---|---|---|
role | "user" | "assistant" | "system" | Required |
name? | string | |
time? | string | |
model? | string | |
text? | string | |
streaming? | boolean | |
tint? | Tint | |
sources? | Source[] | |
attachments? | { name: string; size?: string; kind?: string }[] | |
usage? | string | |
onRetry? | () => void | |
onFeedback? | (v: "up" | "down") => void | |
actions? | boolean | |
before? | ReactNode | |
after? | ReactNode | |
children? | ReactNode | |
feedback? | "up" | "down" | null | |
className? | string | Extra class on the root element. |
style? | CSSProperties | Inline style on the root element. |