Skip to content
uifiles
Browse components
ChatComponent

Message Response

Markdown renderer for streamed AI assistant output. MessageResponse wraps Streamdown with the cjk, code (Shiki), math (KaTeX) and mermaid plugins, tolerates incomplete markdown while tokens arrive, and is memoized on children/isAnimating so a chat list does not re-render every block on each token. Use it as the body of an assistant message; accepts every Streamdown prop.

pnpm dlx shadcn@latest add @uifiles/response

Streamed markdown

Headings, a fence, a table, inline and display math and a link, as Streamdown renders them. The wide formula scrolls in its own box.

Choosing a cache strategy

Streamed markdown renders incrementally as tokens arrive, including incomplete fences and tables.

ts
export async function getUser(id: string) {  const res = await fetch(`/api/users/${id}`, { next: { revalidate: 60 } })  if (!res.ok) throw new Error("Failed to load user")  return res.json() as Promise<{ id: string; name: string }>}
StrategyFreshnessCost
no-storeAlways freshHighest
revalidate: 60Up to 60s staleLow
force-cacheUntil redeployLowest

For a cache hit rate of h, the effective cost per request is:

ceff=h⋅chit+(1−h)⋅cmissc_{\text{eff}} = h \cdot c_{\text{hit}} + (1 - h) \cdot c_{\text{miss}}

A regularized logistic loss is wider than a phone, so it scrolls on its own instead of widening the page:

L(θ)=−1n∑i=1n[yilog⁡σ(θ⊤xi)+(1−yi)log⁡(1−σ(θ⊤xi))]+λ∥θ∥22\mathcal{L}(\theta) = -\frac{1}{n} \sum_{i=1}^{n} \left[ y_i \log \sigma(\theta^\top x_i) + (1 - y_i) \log\left(1 - \sigma(\theta^\top x_i)\right) \right] + \lambda \lVert \theta \rVert_2^2

Tip: keep the chunk size small so partial output paints early. Links such as the ask before they open.