opt-chat
AI SDK 기반 채팅 인터페이스 컴포넌트 라이브러리. 70+ 컴포넌트로 스트리밍, 메시지 파트, 도구 호출, 코드 하이라이팅을 지원합니다.
reopt design업데이트
1. 왜 opt-chat인가
AI SDK의 useChat은 강력하지만, 실제 채팅 UI를 만들려면 스트리밍 렌더링, 메시지 파트 분류, 도구 호출 표시, 코드 하이라이팅 등 수십 가지 UI 문제를 직접 해결해야 합니다. opt-chat은 이 모든 것을 70+ 컴포넌트로 제공하면서도, opt-ui 디자인 토큰과 자연스럽게 통합됩니다.
AI SDK useChat 래퍼
Vercel AI SDK의 useChat을 감싸서 스트리밍, 도구 호출, 멀티파트 메시지를 자동 처리합니다.
턴 앵커링 스크롤 엔진
전송한 질문이 하단으로 튀지 않고 뷰포트 상단에 정착합니다. 위로 스크롤하면 팔로우가 해제되고 위치가 보존됩니다.
한국어 기본 + 일괄 로케일 전환
모든 레이블이 한국어 기본값을 제공하며, koLabels/enLabels 카탈로그로 일괄 전환할 수 있습니다.
opt-ui 테마 호환
opt-ui의 --opt-* CSS 변수와 CHAT_* 토큰이 자동 매핑되고, 코드 블록은 라이트/다크 듀얼 테마를 지원합니다.
2. 아키텍처
opt-chat은 세 개의 모듈로 구성됩니다. core가 세션과 메시지 흐름을 관리하고, parts가 각 메시지 타입별 렌더러를 제공하며, input이 프롬프트 입력을 보조합니다.
| 모듈 | 역할 | 주요 컴포넌트 |
|---|---|---|
| core | 대화 세션 관리, 스크롤 엔진, 메시지 렌더링 | Conversation, ConversationMessage, Message, PromptInput(+ActionMenu/Select/Command), MessageParts, Shimmer, useChatSession |
| parts | 메시지 파트별 전용 렌더러 (30+ 컴포넌트) | Reasoning, Tool, CodeBlock, Sources, Artifact, Context, Plan, ChainOfThought, Terminal, FileTree, StackTrace, TestResults, Transcript, Image, Snippet, Confirmation ... |
| input | 프롬프트 입력 보조 컴포넌트 | ModelSelector, Attachments, SpeechInput, VoiceSelector, MicSelector, Suggestion ... |
| flow | 에이전트 그래프 캔버스 (subpath: @reopt-ai/opt-chat/flow) | Canvas, Connection, Edge.Animated, Node, Panel, Controls, Toolbar |
3. 빠른 시작
useChatSession으로 AI SDK 세션을 생성하고, Conversation으로 감싼 뒤 Message와 PromptInput을 배치하면 기본 채팅 UI가 완성됩니다.
"use client";
import { DefaultChatTransport } from "ai";
import {
useChatSession,
Conversation,
ConversationContent,
ConversationMessage,
ConversationScrollButton,
Message,
MessageContent,
MessageParts,
PromptInput,
PromptInputAttachments,
PromptInputTextarea,
PromptInputFooter,
PromptInputSubmit,
} from "@reopt-ai/opt-chat";
export default function ChatPage() {
const session = useChatSession({
transport: new DefaultChatTransport({ api: "/api/chat" }),
});
return (
<div className="flex h-dvh flex-col">
<Conversation>
<ConversationContent>
{session.messages.map((msg) => (
// user 턴에 scrollAnchor — 전송 시 질문이 상단에 정착
<ConversationMessage
key={msg.id}
messageId={msg.id}
scrollAnchor={msg.role === "user"}
>
<Message from={msg.role}>
<MessageContent>
<MessageParts parts={msg.parts} isStreaming={session.isStreaming} />
</MessageContent>
</Message>
</ConversationMessage>
))}
</ConversationContent>
<ConversationScrollButton />
</Conversation>
<PromptInput onSubmit={session.handleSubmit}>
<PromptInputAttachments />
<PromptInputTextarea />
<PromptInputFooter>
<PromptInputSubmit />
</PromptInputFooter>
</PromptInput>
</div>
);
}4. 다음 문서
시작하기
설치, 피어 의존성, CSS 설정까지 빠른 시작 가이드
핵심 컴포넌트
Conversation, Message, PromptInput 등 core 모듈 상세
메시지 파트
Reasoning, Tool, CodeBlock 등 30+ 파트 카탈로그
스타일링
CHAT_* 토큰 시스템과 opt-ui 테마 연동
도구 승인
도구 호출 승인/거부 UX 패턴 구현
커스텀 파트
renderPart 콜백으로 맞춤 메시지 파트 작성
Production readiness
install smoke, browser matrix, streaming soak, release gate
0.1 → 0.2 마이그레이션
MessageBranch API 변경, PromptInput 헬퍼 노출, styles.css