useChat Hook
The useChat
hook is the core logic provider in @ulifeai/agentb-ui
for building chat interfaces. It manages communication with the AgentB backend, processes Server-Sent Events (SSE), and maintains the state of the conversation. The <AgentBChat />
component uses this hook internally.
Import:
import { useChat, UseChatOptions, UseChatReturn, ChatMessage } from '@ulifeai/agentb-ui';
// Or from '@ulifeai/agentb-ui/hooks/useChat' depending on package structure
useChat(options: UseChatOptions): UseChatReturn
useChat(options: UseChatOptions): UseChatReturn
UseChatOptions
(Input)
UseChatOptions
(Input)An object to configure the useChat
hook:
backendUrl: string
(Required):The full URL of your AgentB backend's streaming SSE endpoint (e.g.,
http://localhost:3001/agent/stream
).
initialThreadId?: string
:Optional. If provided, the hook will attempt to use this thread ID for the conversation. Useful for resuming existing conversations.
If not provided, a new
threadId
might be generated by the backend (if the backend'sgetThreadId
callback creates one) or a temporary UI-generated one might be used initially, which gets confirmed/updated by the first event from the backend that contains athreadId
.
initialMessages?: ChatMessage[]
:Optional. An array of
ChatMessage
objects to pre-populate the chat interface. Useful for welcome messages or loading conversation history.
ChatMessage
Interface (for initialMessages
and messages
return value):
interface ChatMessage {
id: string; // Unique message ID
text: string; // Main display text
sender: 'user' | 'ai' | 'system' | 'tool_thought' | 'tool_executing' | 'tool_result';
timestamp: string; // ISO string
status: 'sending' | 'sent' | 'failed' | 'streaming' | 'in_progress' | 'completed' | 'error';
metadata?: {
eventType?: AgentEvent['type'];
toolName?: string;
toolInput?: Record<string, any> | string;
toolOutput?: any;
isError?: boolean;
stepId?: string;
originalEvent?: AgentEvent; // Full backend event
};
}
UseChatReturn
(Output)
UseChatReturn
(Output)An object containing state and functions to manage the chat:
messages: ChatMessage[]
:An array of
ChatMessage
objects representing the current state of the conversation. This array is reactive and updates as new events are processed from the backend.
sendMessage: (text: string) => Promise<void>
:An asynchronous function to send a new user message to the backend.
text: string
: The content of the user's message.It handles creating the user message in the UI, sending the request to
backendUrl
, and then processing the subsequent SSE stream ofAgentEvent
s.
isLoading: boolean
:true
when a user message has been sent and the hook is waiting for the initial response or start of the stream from the backend (before anythread.message.delta
for the assistant has arrived).false
otherwise.
isStreaming: boolean
:true
if the assistant is currently streaming a text response (i.e.,thread.message.delta
events withcontentChunk
are being received for an active assistant message).false
otherwise.
error: string | null
:Contains an error message string if an error occurred during the
sendMessage
process or while handling the stream.null
if there are no errors.
threadId: string | null
:The current conversation thread ID.
It's initialized with
initialThreadId
if provided, or updated by the backend from the first event containing athreadId
. Can benull
initially if noinitialThreadId
is given and no backend events have been received yet.
setMessages: React.Dispatch<React.SetStateAction<ChatMessage[]>>
:The React state setter function for the
messages
array.Allows direct manipulation of the displayed messages, though this should be used with caution as the hook normally manages this state based on backend events. Useful for scenarios like optimistically adding messages or clearing the chat.
currentRunId: string | null
:The
runId
of the currently active agent execution on the backend.null
if no run is active.
How useChat
Works Internally
useChat
Works InternallyInitialization:
Sets up internal state for messages, loading status, thread ID, etc.
Uses
initialMessages
andinitialThreadId
if provided.
sendMessage(text)
Call:Adds the user's message to the
messages
array withstatus: 'sending'
.Sets
isLoading: true
.Resets internal accumulators for assistant responses and tool call message tracking.
Makes a
POST
request to thebackendUrl
with the user's message (content: text
) and the currentthreadId
. The request headers typically includeAccept: text/event-stream
.The backend is expected to respond with an SSE stream.
Updates the user message status to
sent
once the request is successfully initiated.Obtains a
ReadableStreamDefaultReader
from the response body.
SSE Stream Processing:
Uses the
parseSSEStream
utility (fromui/src/api.ts
) to consume and parseAgentEvent
s from the stream reader.For each
AgentEvent
:Updates
threadId
andcurrentRunId
: If the event contains these IDs and they are new or different, the hook's state is updated.Transforms
AgentEvent
toChatMessage
: Logic within the hook (specificallyupsertMessage
andaddChatMessage
callbacks) processes differentAgentEvent.type
s:thread.message.created
(assistant,inProgress: true
): Creates a new assistantChatMessage
withstatus: 'streaming'
. AnactiveAssistantMessageIdRef
is set to track this message.thread.message.delta
(contentChunk
): Appends thecontentChunk
to the text of the active assistant message. SetsisStreaming: true
.thread.message.delta
(toolCallsChunk
): May update metadata for the active assistant message or create/update separateChatMessage
s of typetool_thought
if the UI is designed to show tool calls as they are being formed by the LLM (though more commonly, full tool call info comes fromthread.message.completed
or dedicated tool events).thread.message.completed
(assistant): Finalizes the text of the active assistant message, sets itsstatus: 'sent'
, and potentially updates its timestamp andoriginalEvent
. SetsisStreaming: false
.thread.run.step.tool_call.created
: Creates aChatMessage
withsender: 'tool_thought'
, text like "Agent plans to use tool X...", andstatus: 'in_progress'
. MapstoolCall.id
to thisChatMessage.id
for later updates.agent.tool.execution.started
: Updates the correspondingtool_thought
message tosender: 'tool_executing'
with text like "Executing tool X...".agent.tool.execution.completed
: Updates the corresponding message tosender: 'tool_result'
, text reflecting success/failure, and status'completed'
or'error'
. StorestoolOutput
andisError
in metadata.agent.sub_agent.invocation.completed
: Similar toagent.tool.execution.completed
, but updates the message related to theDelegateToSpecialistTool
call, often including details about the sub-agent.thread.run.failed
: Sets the globalerror
state, updates any active assistant message tostatus: 'failed'
, and setsisLoading: false
,isStreaming: false
.thread.run.completed
: SetsisLoading: false
,isStreaming: false
. Finalizes any active assistant message.Other events might create 'system' messages or update metadata.
Updates the
messages
state array, triggering UI re-renders.
Stream End / Error:
When the stream ends (either normally or due to an error),
isLoading
andisStreaming
are set tofalse
.If an error occurred during fetching or parsing the stream, the
error
state is set.The
ReadableStreamDefaultReader
is released.
Example Usage
Refer to the UI Integration Guide for a practical example of using useChat
to build a custom chat interface.
The useChat
hook is the powerhouse behind @ulifeai/agentb-ui
, providing all the necessary client-side logic for a fully interactive and streaming chat experience with your AgentB backend.
Last updated