--- title: Agent Inbox --- ```js import {API, apiFetch, pollDelay, waitForVisible} from "./components/config.js"; ``` ```js // Live poll: messages list const inboxState = (async function*() { let failures = 0; while (true) { let messages = [], ok = false; try { const resp = await apiFetch("/messages/?limit=100"); ok = resp.ok; if (ok) messages = await resp.json(); } catch {} failures = ok ? 0 : failures + 1; yield {messages, ok, ts: new Date()}; await waitForVisible(pollDelay({ok, failures})); } })(); ``` ```js const messages = inboxState.messages ?? []; const _ok = inboxState.ok ?? false; const _ts = inboxState.ts; const unread = messages.filter(m => !m.read_at && !m.archived_at); const read = messages.filter(m => m.read_at && !m.archived_at); const archived = messages.filter(m => m.archived_at); // Group unread by agent for KPI const agentCounts = {}; for (const m of unread) { agentCounts[m.to_agent] = (agentCounts[m.to_agent] ?? 0) + 1; } const topAgents = Object.entries(agentCounts).sort((a, b) => b[1] - a[1]).slice(0, 4); ``` # Agent Inbox ```js import {injectTocTop} from "./components/toc-sidebar.js"; import {withDocHelp} from "./components/doc-overlay.js"; const _kpiBox = html`
Inbox
unread
${unread.length}
total
${messages.length}
${topAgents.map(([agent, count]) => html`
${agent}
${count}
`)}
`; const _liveEl = html`
${_ok ? `Live · updated ${_ts?.toLocaleTimeString()}` : html`Offline — run: make api`}
`; injectTocTop("inbox-kpi-box", _kpiBox); injectTocTop("live-indicator", _liveEl); ``` Inter-agent coordination messages. Agents send messages via `send_message()` MCP tool and read them via `get_messages()`. --- ## Unread ```js function fmtDate(s) { if (!s) return "—"; const d = new Date(s); return d.toLocaleDateString() + " " + d.toLocaleTimeString([], {hour: "2-digit", minute: "2-digit"}); } function renderMessage(m, showMarkRead = false) { const isBroadcast = m.to_agent === "broadcast"; const borderColor = !m.read_at ? "#d97706" : "#6b7280"; async function onMarkRead() { await fetch(`${API}/messages/${m.id}/read`, {method: "PATCH"}); } async function onArchive() { await fetch(`${API}/messages/${m.id}/archive`, {method: "PATCH"}); } return html`
${m.from_agent} ${m.to_agent} ${fmtDate(m.created_at)}
${showMarkRead ? html`` : ""}
${m.subject}
body
${m.body}
${m.thread_id ? html`
thread: ${m.thread_id}
` : ""}
`; } if (unread.length === 0) { display(html`

No unread messages.

`); } else { display(html`
${unread.map(m => renderMessage(m, true))}
`); } ``` --- ## Read ```js if (read.length === 0) { display(html`

No read messages.

`); } else { display(html`
${read.map(m => renderMessage(m, false))}
`); } ``` --- ## Archived ```js if (archived.length === 0) { display(html`

No archived messages.

`); } else { display(html`
${archived.map(m => renderMessage(m, false))}
`); } ```