use-send-agent-message.ts
Overview
use-send-agent-message.ts is a utility and React hook file designed to manage the sending and receiving of agent chat messages in a chat system, specifically for interactions with an AI or automated agent backend. It provides utility functions to parse message and input events, manage file uploads, and a comprehensive React hook useSendAgentMessage that handles message input, sending messages via Server-Sent Events (SSE), session management, message state updates, and integration with related UI and application context.
The file integrates with various parts of the system such as the chat UI components, API utilities, localization, state management stores, and custom hooks handling message logic and graph queries. Its purpose is to abstract the complexities of message lifecycle management and provide an easy-to-use interface for chat message sending workflows.
Detailed Explanations
Utility Functions
findMessageFromList(eventList: IEventList)
Purpose: Parses a list of chat events (
eventList) to extract a combined message content string, handling special<think>tags that denote thought processing periods within messages.Parameters:
eventList: IEventList— an array of event objects representing chat message events.
Returns: An object with:
id: string | undefined— the message ID from the first event.content: string— the concatenated message content with<think>tags appropriately added.
Usage Example:
const message = findMessageFromList(eventList); console.log(message.content);Details:
Filters events to only those with type
MessageEventType.Message.Concatenates content, wrapping segments between
start_to_thinkandend_to_thinkflags in<think></think>tags.Ensures that if a
start_to_thinkis found without a correspondingend_to_think, it still closes with</think>.
findInputFromList(eventList: IEventList)
Purpose: Extracts user input data from the event list.
Parameters:
eventList: IEventList— array of events.
Returns: An object containing:
id: string | undefined— message ID of the input event.data: any— input data associated with the event.
Usage Example:
const input = findInputFromList(eventList); console.log(input.data);
getLatestError(eventList: IEventList)
Purpose: Retrieves the latest error message from the last event in the list.
Parameters:
eventList: IEventList
Returns: The value of
_ERRORfield in the outputs of the last event, if any.Implementation: Uses lodash
getto safely access nested error data.
useGetBeginNodePrologue()
Purpose: Custom hook to retrieve an optional "prologue" text configured in a special "begin node" in the graph state.
Returns: The prologue string if enabled; otherwise
undefined.Usage Example:
const prologue = useGetBeginNodePrologue(); if (prologue) { // show prologue in UI }
useFindMessageReference(answerList: IEventList)
Purpose: React hook to find reference metadata associated with a message ID from message end events.
Parameters:
answerList: IEventList— list of answer events.
Returns: An object with the method:
findReferenceByMessageId(messageId: string): any— returns reference data for a given message ID.
Details:
Maintains an internal state of message end events.
Updates this list when new message end events appear in the
answerList.
useSetUploadResponseData()
Purpose: Custom hook to manage uploaded file response data and the corresponding file objects.
Returns: An object with upload state and actions:
uploadResponseList: UploadResponseDataType[]— list of upload metadata.fileList: File[]— list of file objects.setUploadResponseList— setter for upload response list.appendUploadResponseList(data: UploadResponseDataType, files: File[])— appends upload data and files.clearUploadResponseList()— clears all upload data and files.
Usage Example:
const { appendUploadResponseList, uploadResponseList } = useSetUploadResponseData(); appendUploadResponseList(uploadResp, files);
buildRequestBody(value: string = '')
Purpose: Helper function to build a message request object for sending.
Parameters:
value: string— the message content.
Returns: An object representing the message with:
id: string— a generated UUID.content: string— trimmed message content.role: MessageType— set asUser.
Usage Example:
const messageBody = buildRequestBody('Hello');
Main Hook
useSendAgentMessage(options)
Purpose: Central React hook managing the sending of messages to an agent backend, handling SSE streaming responses, session management, message state updates, and integration with UI and context.
Parameters:
options: {url?: string— optional custom URL for sending messages (defaults to internal API).addEventList?: (data: IEventList, messageId: string) => void— callback to add events externally.beginParams?: any[]— optional initial parameters for beginning queries.isShared?: boolean— flag indicating shared mode.refetch?: () => void— optional refetch function to reload message list or data after sending.
}
Returns: An object containing:
value: string— the current input message value.sendLoading: boolean— indicates if a message is currently being sent.derivedMessages: any[]— processed messages for UI consumption.scrollRef: React.RefObject— ref to scroll container.messageContainerRef: React.RefObject— ref to message container element.handlePressEnter: () => void— function to handle pressing Enter to send message.handleInputChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void— handler for input changes.removeMessageById: (id: string) => void— remove a message by its ID.stopOutputMessage: () => void— stops ongoing message streaming.send: (params: Record<string, any>) => Promise<any>— low-level send message function.sendFormMessage: (body: { id?: string; inputs: Record<string, BeginQuery> }) => Promise<void>— sends a message based on form inputs.resetSession: () => void— resets the current chat session.findReferenceByMessageId: (messageId: string) => any— finds references by message ID.appendUploadResponseList: (data: UploadResponseDataType, files: File[]) => void— appends uploaded file data.addNewestOneAnswer: (answer: any) => void— adds a new answer to the message list.sendMessage: (args: { message: Message; beginInputs?: BeginQuery[] }) => Promise<void>— sends a user message with optional inputs.
Usage Example:
const {
value,
sendLoading,
handlePressEnter,
handleInputChange,
derivedMessages,
resetSession,
} = useSendAgentMessage({
url: '/api/send-message',
refetch: loadMessages,
});
// In JSX:
<input
value={value}
onChange={handleInputChange}
onKeyDown={(e) => e.key === 'Enter' && handlePressEnter()}
/>
Implementation Details:
Uses many related hooks and contexts to handle message input, graph data, session state, and message list updates.
Supports a "task mode" where an empty message is sent automatically once.
Supports managing uploaded files and appending them to message parameters.
Manages SSE communication via
useSendMessageBySSE.Handles errors via UI messages using
sonnerMessage.Updates message lists and scrolls the UI to bottom on new messages.
Integrates with localization for UI texts.
Supports resetting the chat session cleanly.
Important Implementation Details and Algorithms
Message Parsing: The function
findMessageFromListcarefully reconstructs message content from streaming events, inserting<think></think>tags to denote "thinking" states between start and end flags, ensuring output content properly represents the agent's thought process.SSE Streaming Handling: The hook leverages
useSendMessageBySSEto send messages and receive incremental streaming responses, updating the UI in near real-time.Session Management: The hook tracks a
sessionIdprovided by the backend in responses and uses it for subsequent message sends to maintain stateful conversations.File Upload Management: Uploaded files are tracked separately, and their metadata is appended to message send parameters.
Task Mode Auto-Send: When in task mode, the hook automatically sends an empty message once to start processing.
State Synchronization: The hook listens for changes in the answer list to update the UI message list and calls external callbacks to notify other parts of the system.
Interaction with Other Parts of the System
UI Components: Imports UI message component (
sonnerMessage) for error display.Constants: Uses
MessageTypeand event types from constants and interfaces for standardized message processing.Hooks: Depends heavily on custom hooks for message input handling (
useHandleMessageInputChange), derived message selection (useSelectDerivedMessages), sending messages (useSendMessageBySSE), and graph data querying (useSelectBeginNodeDataInputs,useIsTaskMode).Graph Store & Context: Uses
useGraphStoreto retrieve node data andAgentChatLogContextfor managing chat log state externally.API & Utilities: Uses internal API util
api.runCanvasas default message sending endpoint; uses lodash utilities for safe data access and trimming.Localization: Integrates with
i18nfor localized UI strings.Form Data Handling: Converts form input arrays into objects with
transferInputsArrayToObject.
Visual Diagram
classDiagram
class useSendAgentMessage {
+value: string
+sendLoading: boolean
+derivedMessages: array
+scrollRef: RefObject
+messageContainerRef: RefObject
+handlePressEnter()
+handleInputChange(event)
+removeMessageById(id)
+stopOutputMessage()
+send(params)
+sendFormMessage(body)
+resetSession()
+findReferenceByMessageId(messageId)
+appendUploadResponseList(data, files)
+addNewestOneAnswer(answer)
+sendMessage(args)
}
class findMessageFromList {
+eventList: IEventList
+return {id, content}
}
class findInputFromList {
+eventList: IEventList
+return {id, data}
}
class getLatestError {
+eventList: IEventList
+return error string
}
class useFindMessageReference {
+answerList: IEventList
+findReferenceByMessageId(messageId)
}
class useSetUploadResponseData {
+uploadResponseList: array
+fileList: array
+append(data, files)
+clear()
}
useSendAgentMessage --> useHandleMessageInputChange
useSendAgentMessage --> useSelectDerivedMessages
useSendAgentMessage --> useSendMessageBySSE
useSendAgentMessage --> useFindMessageReference
useSendAgentMessage --> useSetUploadResponseData
useSendAgentMessage --> useGetBeginNodePrologue
useSendAgentMessage --> useIsTaskMode
useSendAgentMessage --> useSelectBeginNodeDataInputs
useSendAgentMessage --> AgentChatLogContext
Summary
use-send-agent-message.ts encapsulates the full lifecycle of sending and receiving agent chat messages, including message input handling, SSE communication, session and error management, and UI integration. It provides reusable utility functions for parsing message events and user inputs and a rich React hook to integrate message sending logic seamlessly into React components. The file plays a central role in the chat system's interaction with the agent backend, ensuring smooth and stateful messaging experiences.