chat ui

visual building blocks: chat container, messages, input, and status indicators.

examples

chat container

grid layout wrapper with structure: header, messages (scrollable), and input.

preview
header slot
Hello! Can you help me?
Of course! I'd be happy to help. What do you need assistance with?

message bubble

styled container for messages. user messages align right with background, assistant messages align left without background.

preview
This is a user message with a muted background.
This is an assistant message that renders **markdown** and can include `code blocks`, lists, and other formatting.
User messages are right-aligned and capped at 70% width for readability.

chat input

auto-resizing textarea with file upload support, drag-and-drop, and @file references for uploaded files.

preview

message status indicator

shows when the assistant is thinking or generating a response.

preview
thinking...

installation

bash
1npx shadcn@latest add https://ui.inference.sh/r/chat

usage

chat provides low-level primitives for building chat interfaces. wrap your components with AgentChatProvider from @inferencesh/sdk/agent to provide state management.

tsx
1import { Inference } from '@inferencesh/sdk'2import { AgentChatProvider } from '@inferencesh/sdk/agent'3import { ChatContainer } from '@/components/infsh/agent/chat-container'4import { ChatInput } from '@/components/infsh/agent/chat-input'5import { ChatMessages } from '@/components/infsh/agent/chat-messages'6import { MessageBubble } from '@/components/infsh/agent/message-bubble'7import { MessageContent } from '@/components/infsh/agent/message-content'8import { useMemo } from 'react'910export function Chat() {11  const client = useMemo(() => new Inference({ proxyUrl: '/api/inference/proxy' }), [])1213  return (14    <AgentChatProvider15      client={client}16      agentConfig={{17        core_app: { ref: 'openrouter/claude-haiku-45@1ps10tmc' },18        description: 'A helpful assistant',19      }}20    >21      <ChatContainer>22        <ChatMessages>23          {({ messages }) => messages.map(m => (24            <MessageBubble key={m.id} message={m}>25              <MessageContent message={m} />26            </MessageBubble>27          ))}28        </ChatMessages>29        <ChatInput />30      </ChatContainer>31    </AgentChatProvider>32  )33}