1
1
"use client"
2
2
3
- import React , { useState , useEffect , useRef , useCallback } from "react" ;
4
- import type { Tool } from "@gptscript-ai/gptscript" ;
3
+ import React , { useEffect , useContext , useCallback , useRef } from "react" ;
5
4
import Messages , { MessageType } from "@/components/script/messages" ;
6
5
import ChatBar from "@/components/script/chatBar" ;
7
6
import ToolForm from "@/components/script/form" ;
8
7
import Loading from "@/components/loading" ;
9
- import useChatSocket from '@/components/script/useChatSocket' ;
10
8
import { Button } from "@nextui-org/react" ;
11
- import { fetchScript , path } from "@/actions/scripts/fetch" ;
12
9
import { getWorkspaceDir } from "@/actions/workspace" ;
13
10
import { createThread , getThreads , generateThreadName , renameThread , Thread } from "@/actions/threads" ;
14
- import debounce from "lodash/debounce" ;
11
+ import { ScriptContext } from "@/contexts/script" ;
12
+ import { fetchScript , path } from "@/actions/scripts/fetch" ;
15
13
16
14
interface ScriptProps {
17
15
file : string ;
@@ -23,59 +21,38 @@ interface ScriptProps {
23
21
setSelectedThreadId ?: React . Dispatch < React . SetStateAction < string | null > >
24
22
}
25
23
26
- const Script : React . FC < ScriptProps > = ( { file, thread, setThreads, className, messagesHeight = 'h-full' , enableThreads, setSelectedThreadId} ) => {
27
- const [ tool , setTool ] = useState < Tool > ( { } as Tool ) ;
28
- const [ showForm , setShowForm ] = useState ( true ) ;
29
- const [ formValues , setFormValues ] = useState < Record < string , string > > ( { } ) ;
30
- const [ inputValue , setInputValue ] = useState ( '' ) ;
24
+ const Script : React . FC < ScriptProps > = ( { className, messagesHeight = 'h-full' , enableThreads} ) => {
31
25
const inputRef = useRef < HTMLInputElement > ( null ) ;
32
- const [ hasRun , setHasRun ] = useState ( false ) ;
33
- const [ hasParams , setHasParams ] = useState ( false ) ;
34
- const [ isEmpty , setIsEmpty ] = useState ( false ) ;
26
+ const [ inputValue , setInputValue ] = React . useState < string > ( "" ) ;
35
27
const {
36
- socket, connected, running, messages, setMessages, restart, interrupt, generating, error
37
- } = useChatSocket ( isEmpty ) ;
38
-
39
- const fetchThreads = async ( ) => {
40
- if ( ! setThreads ) return ;
41
- const threads = await getThreads ( ) ;
42
- setThreads ( threads ) ;
43
- } ;
44
-
45
- useEffect ( ( ) => {
46
- setHasParams ( tool . arguments ?. properties != undefined && Object . keys ( tool . arguments ?. properties ) . length > 0 ) ;
47
- setIsEmpty ( ! tool . instructions ) ;
48
- } , [ tool ] ) ;
49
-
50
- useEffect ( ( ) => {
51
- if ( thread ) restartScript ( ) ;
52
- } , [ thread ] ) ;
53
-
54
- useEffect ( ( ) => {
55
- if ( hasRun || ! socket || ! connected ) return ;
56
- if ( ! tool . arguments ?. properties || Object . keys ( tool . arguments . properties ) . length === 0 ) {
57
- path ( file )
58
- . then ( async ( path ) => {
59
- const workspace = await getWorkspaceDir ( )
60
- return { path, workspace}
61
- } )
62
- . then ( ( { path, workspace} ) => {
63
- socket . emit ( "run" , path , tool . name , formValues , workspace , thread )
64
- } ) ;
65
- setHasRun ( true ) ;
66
- }
67
- } , [ tool , connected , file , formValues , thread ] ) ;
28
+ script,
29
+ tool,
30
+ showForm,
31
+ setShowForm,
32
+ formValues,
33
+ setFormValues,
34
+ setHasRun,
35
+ hasParams,
36
+ messages,
37
+ setMessages,
38
+ thread,
39
+ setThreads,
40
+ setSelectedThreadId,
41
+ socket,
42
+ connected,
43
+ running,
44
+ generating,
45
+ restartScript,
46
+ interrupt,
47
+ fetchThreads,
48
+ } = useContext ( ScriptContext ) ;
68
49
69
50
useEffect ( ( ) => {
70
51
if ( inputRef . current ) {
71
52
inputRef . current . focus ( ) ;
72
53
}
73
54
} , [ messages , inputValue ] ) ;
74
55
75
- useEffect ( ( ) => {
76
- fetchScript ( file ) . then ( ( data ) => setTool ( data ) ) ;
77
- } , [ ] ) ;
78
-
79
56
useEffect ( ( ) => {
80
57
const smallBody = document . getElementById ( "small-message" ) ;
81
58
if ( smallBody ) smallBody . scrollTop = smallBody . scrollHeight ;
@@ -84,7 +61,7 @@ const Script: React.FC<ScriptProps> = ({file, thread, setThreads, className, mes
84
61
const handleFormSubmit = ( ) => {
85
62
setShowForm ( false ) ;
86
63
setMessages ( [ ] ) ;
87
- path ( file )
64
+ path ( script )
88
65
. then ( async ( path ) => {
89
66
const workspace = await getWorkspaceDir ( )
90
67
return { path, workspace}
@@ -107,7 +84,7 @@ const Script: React.FC<ScriptProps> = ({file, thread, setThreads, className, mes
107
84
108
85
let threadId = "" ;
109
86
if ( hasNoUserMessages ( ) && enableThreads && ! thread && setThreads && setSelectedThreadId ) {
110
- const newThread = await createThread ( file , message )
87
+ const newThread = await createThread ( script , message )
111
88
threadId = newThread ?. meta ?. id ;
112
89
setThreads ( await getThreads ( ) ) ;
113
90
setSelectedThreadId ( threadId ) ;
@@ -124,18 +101,6 @@ const Script: React.FC<ScriptProps> = ({file, thread, setThreads, className, mes
124
101
125
102
} ;
126
103
127
- const restartScript = useCallback (
128
- // This is debonced as allowing the user to spam the restart button can cause race
129
- // conditions. In particular, the restart may not be processed correctly and can
130
- // get the user into a state where no run has been sent to the server.
131
- debounce ( async ( ) => {
132
- setTool ( await fetchScript ( file ) ) ;
133
- restart ( ) ;
134
- setHasRun ( false ) ;
135
- } , 200 ) ,
136
- [ file , restart ]
137
- ) ;
138
-
139
104
const hasNoUserMessages = useCallback ( ( ) => messages . filter ( ( m ) => m . type === MessageType . User ) . length === 0 , [ messages ] ) ;
140
105
141
106
return (
0 commit comments