const isMessageAIGenerated = (message) => !!message.ai_generated;
const MyAIStateIndicator = () => {
const { aiState } = useAIState();
return aiState === AIStates.Thinking ? (
<View>
<Text>The chat-bot is currently thinking...</Text>
</View>
) : null;
};
const App = () => (
<Chat client={client} isMessageAIGenerated={isMessageAIGenerated}>
<Channel channel={channel}>
<MessageList />
<MyAIStateIndicator />
<MessageInput />
</Channel>
</Chat>
);Hooks
The SDK provides two hooks to help customize AI-related UI.
Best Practices
- Use
useAIStateto drive minimal, clear UI state changes. - Keep AI indicators lightweight to avoid re-rendering large trees.
- Use
useStreamingMessageonly for AI messages to avoid slowing normal text. - Tune
letterInterval/renderingLetterCountfor readability and performance. - Always fall back to the original message text when streaming is disabled.
useAIState
Returns the current AI state for a channel.
Example usage
This shows a custom indicator only while the AI is in AI_STATE_THINKING.
useStreamingMessage
Returns text in a streamed, typewriter fashion. Configure speed with letterInterval and renderingLetterCount.
Example usage
const isMessageAIGenerated = (message) => !!message.ai_generated;
const MyStreamedMessageText = ({ message: messageFromProps }) => {
const { message: messageFromContext } = useMessageContext();
const { text = "" } = messageFromProps || messageFromContext;
const { streamedMessageText } = useStreamingMessage({
renderingLetterCount: 2,
letterInterval: 30,
text,
});
const message = messageFromProps || messageFromContext;
return (
<MessageTextContainer message={{ ...message, text: streamedMessageText }} />
);
};
const App = () => (
<Chat client={client} isMessageAIGenerated={isMessageAIGenerated}>
<Channel channel={channel} StreamedMessageText={MyStreamedMessageText}>
<MessageList />
<MessageInput />
</Channel>
</Chat>
);This overrides the default StreamedMessageText and slows the typewriter animation via useStreamingMessage.