@@ -5,18 +5,18 @@ import { useState, useRef, useEffect } from "react";
55import { ArrowBigUp , X , Loader2 } from "lucide-react" ;
66import { Button } from "@/components/ui/button" ;
77import { Textarea } from "@/components/ui/textarea" ;
8- import type { Session , AgentMessageConfig , TextMessageConfig } from "@/types/datamodel" ;
8+ import type { Session , AgentMessageConfig } from "@/types/datamodel" ;
99import { ScrollArea } from "@/components/ui/scroll-area" ;
1010import ChatMessage from "@/components/chat/ChatMessage" ;
1111import StreamingMessage from "./StreamingMessage" ;
12- import TokenStatsDisplay , { calculateTokenStats } from "./TokenStats" ;
12+ import TokenStatsDisplay from "./TokenStats" ;
1313import { TokenStats } from "@/lib/types" ;
1414import StatusDisplay from "./StatusDisplay" ;
1515import { createSession , getSessionMessages , checkSessionExists , updateSession } from "@/app/actions/sessions" ;
1616import { getCurrentUserId } from "@/app/actions/utils" ;
17- import { messageUtils } from "@/lib/utils" ;
1817import { toast } from "sonner" ;
1918import { useRouter } from "next/navigation" ;
19+ import { createMessageHandlers } from "@/lib/messageHandlers" ;
2020
2121export type ChatStatus = "ready" | "thinking" | "error" ;
2222
@@ -49,6 +49,13 @@ export default function ChatInterface({ selectedAgentId, selectedSession, sessio
4949 const isCreatingSessionRef = useRef < boolean > ( false ) ;
5050 const [ isFirstMessage , setIsFirstMessage ] = useState < boolean > ( ! sessionId ) ;
5151
52+ const { handleMessageEvent } = createMessageHandlers ( {
53+ setMessages,
54+ setIsStreaming,
55+ setStreamingContent,
56+ setTokenStats
57+ } ) ;
58+
5259 useEffect ( ( ) => {
5360 async function initializeChat ( ) {
5461 // Skip completely if this is a first message session creation flow
@@ -251,37 +258,7 @@ export default function ChatInterface({ selectedAgentId, selectedSession, sessio
251258 if ( eventData ) {
252259 try {
253260 const eventDataJson = JSON . parse ( eventData ) as AgentMessageConfig ;
254-
255- if ( messageUtils . isStreamingMessage ( eventDataJson ) ) {
256- // Set the streaming flag to true and concatenate the content
257- setIsStreaming ( true ) ;
258- setStreamingContent ( prev => prev + eventDataJson . content ) ;
259- } else if ( messageUtils . isTextMessageContent ( eventDataJson ) ) {
260- // The model usage is sent within the TextMessage, after the streaming is complete
261- setTokenStats ( prev => calculateTokenStats ( prev , eventDataJson as TextMessageConfig ) ) ;
262- setIsStreaming ( false ) ;
263- setStreamingContent ( "" ) ;
264- if ( eventDataJson . source !== "user" ) {
265- // We don't want to add the user's message to the messages array (again), because
266- // we already added it when the user sent the message.
267- setMessages ( prevMessages => [ ...prevMessages , eventDataJson ] ) ;
268- }
269- }
270- else {
271- // For tool call messages and other non-streaming messages,
272- // add them to the messages array immediately but don't stop streaming
273- if ( messageUtils . isToolCallRequestEvent ( eventDataJson ) ||
274- messageUtils . isToolCallExecutionEvent ( eventDataJson ) ||
275- messageUtils . isToolCallSummaryMessage ( eventDataJson ) ) {
276- // Add tool call messages immediately without stopping streaming
277- setMessages ( prevMessages => [ ...prevMessages , eventDataJson ] ) ;
278- } else {
279- // For other non-tool, non-streaming messages, use original behavior
280- setIsStreaming ( false ) ;
281- setStreamingContent ( "" ) ;
282- setMessages ( prevMessages => [ ...prevMessages , eventDataJson ] ) ;
283- }
284- }
261+ handleMessageEvent ( eventDataJson ) ;
285262 } catch ( error ) {
286263 toast . error ( "Error parsing event data" ) ;
287264 console . error ( "Error parsing event data:" , error , eventData ) ;
0 commit comments