1
1
"use client" ;
2
2
3
- import React , { useState } from "react" ;
3
+ import React , { useEffect , useRef , useState } from "react" ;
4
4
import {
5
5
AppendMessage ,
6
6
AssistantRuntimeProvider ,
@@ -19,37 +19,74 @@ import { SelectModel } from "./SelectModel";
19
19
import { ThreadHistory } from "./thread-history" ;
20
20
import { Toaster } from "./ui/toaster" ;
21
21
import { useGraphContext } from "../contexts/GraphContext" ;
22
+ import { useQueryState } from "nuqs" ;
22
23
23
24
function ChatLangChainComponent ( ) : React . ReactElement {
24
25
const { toast } = useToast ( ) ;
25
26
const { threadsData, userData, graphData } = useGraphContext ( ) ;
26
27
const { userId } = userData ;
27
- const { getUserThreads, threadId : currentThread } = threadsData ;
28
- const { messages, setMessages, streamMessage } = graphData ;
28
+ const { getUserThreads, createThread, getThreadById } = threadsData ;
29
+ const { messages, setMessages, streamMessage, switchSelectedThread } =
30
+ graphData ;
29
31
const [ isRunning , setIsRunning ] = useState ( false ) ;
32
+ const [ threadId , setThreadId ] = useQueryState ( "threadId" ) ;
30
33
31
- const isSubmitDisabled = ! userId || ! currentThread ;
34
+ const hasCheckedThreadIdParam = useRef ( false ) ;
35
+ useEffect ( ( ) => {
36
+ if ( typeof window === "undefined" || hasCheckedThreadIdParam . current )
37
+ return ;
38
+ if ( ! threadId ) {
39
+ hasCheckedThreadIdParam . current = true ;
40
+ return ;
41
+ }
42
+
43
+ hasCheckedThreadIdParam . current = true ;
44
+
45
+ try {
46
+ getThreadById ( threadId ) . then ( ( thread ) => {
47
+ if ( ! thread ) {
48
+ setThreadId ( null ) ;
49
+ return ;
50
+ }
51
+
52
+ switchSelectedThread ( thread ) ;
53
+ } ) ;
54
+ } catch ( e ) {
55
+ console . error ( "Failed to fetch thread in query param" , e ) ;
56
+ setThreadId ( null ) ;
57
+ }
58
+ } , [ threadId ] ) ;
59
+
60
+ const isSubmitDisabled = ! userId ;
32
61
33
62
async function onNew ( message : AppendMessage ) : Promise < void > {
34
63
if ( isSubmitDisabled ) {
35
- let description = "" ;
36
- if ( ! userId ) {
37
- description = "Unable to find user ID. Please try again later." ;
38
- } else if ( ! currentThread ) {
39
- description =
40
- "Unable to find current thread ID. Please try again later." ;
41
- }
42
64
toast ( {
43
65
title : "Failed to send message" ,
44
- description,
66
+ description : "Unable to find user ID. Please try again later." ,
45
67
} ) ;
46
68
return ;
47
69
}
48
70
if ( message . content [ 0 ] ?. type !== "text" ) {
49
71
throw new Error ( "Only text messages are supported" ) ;
50
72
}
73
+
51
74
setIsRunning ( true ) ;
52
75
76
+ let currentThreadId = threadId ;
77
+ if ( ! currentThreadId ) {
78
+ const thread = await createThread ( userId ) ;
79
+ if ( ! thread ) {
80
+ toast ( {
81
+ title : "Error" ,
82
+ description : "Thread creation failed." ,
83
+ } ) ;
84
+ return ;
85
+ }
86
+ setThreadId ( thread . thread_id ) ;
87
+ currentThreadId = thread . thread_id ;
88
+ }
89
+
53
90
try {
54
91
const humanMessage = new HumanMessage ( {
55
92
content : message . content [ 0 ] . text ,
@@ -58,7 +95,7 @@ function ChatLangChainComponent(): React.ReactElement {
58
95
59
96
setMessages ( ( prevMessages ) => [ ...prevMessages , humanMessage ] ) ;
60
97
61
- await streamMessage ( {
98
+ await streamMessage ( currentThreadId , {
62
99
messages : [ convertToOpenAIFormat ( humanMessage ) ] ,
63
100
} ) ;
64
101
} finally {
0 commit comments