usePipecatConversation
Hook that derives a clean, ordered conversation stream from RTVI events.
Overview
usePipecatConversation provides access to conversation state managed by the ConversationProvider. The provider is automatically included when using PipecatAppBase and handles all Pipecat RTVI events to produce a clean message list suitable for rendering a chat transcript. It handles streaming text, placeholder messages, finalization, and merging of consecutive messages from the same role.
Setup
The ConversationProvider is automatically included when you use PipecatAppBase, so no additional setup is required:
import { PipecatAppBase, usePipecatConversation } from "@pipecat-ai/voice-ui-kit";
export default function App() {
return (
<PipecatAppBase
transportType="smallwebrtc"
connectParams={{ webrtcUrl: "/api/offer" }}
>
<YourApp />
</PipecatAppBase>
);
}Usage
Basic
import { usePipecatConversation } from "@pipecat-ai/voice-ui-kit";
export function ConversationList() {
const { messages } = usePipecatConversation();
return (
<ul>
{messages.map((m, i) => (
<li key={i}>
<strong>{m.role}:</strong> {typeof m.content === "string" ? m.content : "[component]"}
</li>
))}
</ul>
);
}With callback
const { messages } = usePipecatConversation({
onMessageAdded: (message) => console.log("New message:", message),
});Full example
import React, { useEffect, useRef } from "react";
import { usePipecatConversation } from "@pipecat-ai/voice-ui-kit";
export function ConversationExample() {
const { messages } = usePipecatConversation();
const endRef = useRef<HTMLDivElement>(null);
useEffect(() => {
endRef.current?.scrollIntoView({ behavior: "smooth" });
}, [messages]);
return (
<div style={{ height: 300, overflow: "auto", fontFamily: "monospace", fontSize: 12 }}>
{messages.map((m, i) => (
<div key={i}>
<strong>[{m.role}]</strong> {typeof m.content === "string" ? m.content : "[component]"}
<span style={{ opacity: 0.6, marginLeft: 8 }}>
{new Date(m.createdAt).toLocaleTimeString()}
</span>
</div>
))}
<div ref={endRef} />
</div>
);
}Injecting messages
You can inject messages directly via the hook, or by using ConsoleTemplate callbacks.
import React from "react";
import { usePipecatConversation } from "@pipecat-ai/voice-ui-kit";
export function InjectViaHook() {
const { injectMessage } = usePipecatConversation();
return (
<button
onClick={() =>
injectMessage({ role: "system", content: "Hello from the system" })
}
>
Inject message
</button>
);
}