2
2
3
3
import type React from "react" ;
4
4
import { useState , useRef , useEffect } from "react" ;
5
- import { ArrowLeft , ArrowRightFromLine , ArrowBigUp , AlertTriangle , CheckCircle , MessageSquare , StopCircle , X } from "lucide-react" ;
5
+ import { ArrowBigUp , X } from "lucide-react" ;
6
6
import { Button } from "@/components/ui/button" ;
7
7
import { Textarea } from "@/components/ui/textarea" ;
8
- import type { Message , RunStatus , Session , Run } from "@/types/datamodel" ;
8
+ import type { Session , Run } from "@/types/datamodel" ;
9
9
import { ScrollArea } from "@/components/ui/scroll-area" ;
10
10
import ChatMessage from "@/components/chat/ChatMessage" ;
11
11
import useChatStore from "@/lib/useChatStore" ;
12
- import { ChatStatus } from "@/lib/ws" ;
13
12
import StreamingMessage from "./StreamingMessage" ;
14
13
import NoMessagesState from "./NoMessagesState" ;
15
-
16
- interface TokenStats {
17
- total : number ;
18
- input : number ;
19
- output : number ;
20
- }
21
-
22
- function calculateTokenStats ( messages : Message [ ] ) : TokenStats {
23
- return messages . reduce (
24
- ( stats , message ) => {
25
- const usage = message . config ?. models_usage ;
26
- if ( usage ) {
27
- return {
28
- total : stats . total + ( usage . prompt_tokens + usage . completion_tokens ) ,
29
- input : stats . input + usage . prompt_tokens ,
30
- output : stats . output + usage . completion_tokens ,
31
- } ;
32
- }
33
- return stats ;
34
- } ,
35
- { total : 0 , input : 0 , output : 0 }
36
- ) ;
37
- }
14
+ import TokenStatsDisplay , { calculateTokenStats } from "./TokenStats" ;
15
+ import { TokenStats } from "@/lib/types" ;
16
+ import StatusDisplay from "./StatusDisplay" ;
17
+ import Link from "next/link" ;
38
18
39
19
interface ChatInterfaceProps {
40
20
selectedTeamId : string ;
41
21
selectedSession ?: Session | null ;
42
22
selectedRun ?: Run | null ;
43
- onNewSession ?: ( ) => void ;
44
23
}
45
24
46
- export default function ChatInterface ( { selectedTeamId, selectedRun, onNewSession } : ChatInterfaceProps ) {
25
+ export default function ChatInterface ( { selectedTeamId, selectedRun } : ChatInterfaceProps ) {
47
26
const containerRef = useRef < HTMLDivElement > ( null ) ;
48
27
const [ message , setMessage ] = useState ( "" ) ;
49
28
const [ tokenStats , setTokenStats ] = useState < TokenStats > ( {
@@ -98,62 +77,6 @@ export default function ChatInterface({ selectedTeamId, selectedRun, onNewSessio
98
77
setMessage ( "" ) ;
99
78
} ;
100
79
101
- const getStatusDisplay = ( chatStatus : ChatStatus , runStatus ?: RunStatus ) => {
102
- switch ( chatStatus ) {
103
- case "error" :
104
- return (
105
- < div className = " text-xs justify-center items-center flex" >
106
- < AlertTriangle size = { 16 } className = "mr-2 text-red-500" />
107
- { run ?. error_message || "An error occurred" }
108
- </ div >
109
- ) ;
110
-
111
- case "ready" :
112
- default :
113
- // If run status is available and indicates a completed state, show that instead
114
- if ( runStatus ) {
115
- switch ( runStatus ) {
116
- case "complete" :
117
- return (
118
- < div className = " text-xs justify-center items-center flex" >
119
- < CheckCircle size = { 16 } className = "mr-2 text-green-500" />
120
- Task completed
121
- </ div >
122
- ) ;
123
- case "error" :
124
- case "timeout" :
125
- return (
126
- < div className = " text-xs justify-center items-center flex" >
127
- < AlertTriangle size = { 16 } className = "mr-2 text-red-500" />
128
- { run ?. error_message || "An error occurred" }
129
- </ div >
130
- ) ;
131
- case "stopped" :
132
- return (
133
- < div className = " text-xs justify-center items-center flex" >
134
- < StopCircle size = { 16 } className = "mr-2 text-orange-500" />
135
- Task was stopped
136
- </ div >
137
- ) ;
138
- default :
139
- return (
140
- < div className = " text-xs justify-center items-center flex" >
141
- < MessageSquare size = { 16 } className = "mr-2" />
142
- Ready
143
- </ div >
144
- ) ;
145
- }
146
- }
147
-
148
- return (
149
- < div className = " text-xs justify-center items-center flex" >
150
- < MessageSquare size = { 16 } className = "mr-2 text-white" />
151
- Ready
152
- </ div >
153
- ) ;
154
- }
155
- } ;
156
-
157
80
const handleKeyDown = ( e : React . KeyboardEvent < HTMLTextAreaElement > ) => {
158
81
if ( ( e . metaKey || e . ctrlKey ) && e . key === "Enter" ) {
159
82
e . preventDefault ( ) ;
@@ -177,7 +100,7 @@ export default function ChatInterface({ selectedTeamId, selectedRun, onNewSessio
177
100
< div className = "flex-1 w-full overflow-hidden relative" >
178
101
< ScrollArea ref = { containerRef } className = "w-full h-full py-12" >
179
102
< div className = "flex flex-col space-y-5" >
180
- { displayMessages . length === 0 && ! showStreamingMessage && < NoMessagesState onNewSession = { onNewSession } /> }
103
+ { displayMessages . length === 0 && ! showStreamingMessage && < NoMessagesState agentId = { selectedTeamId } /> }
181
104
{ displayMessages . map ( ( msg , index ) => (
182
105
< ChatMessage key = { `${ msg . run_id } -${ msg . config . source } -${ index } ` } message = { msg } run = { actualRun } />
183
106
) ) }
@@ -200,21 +123,8 @@ export default function ChatInterface({ selectedTeamId, selectedRun, onNewSessio
200
123
201
124
< div className = "w-full sticky bg-secondary bottom-0 md:bottom-2 rounded-none md:rounded-lg p-4 border overflow-hidden transition-all duration-300 ease-in-out" >
202
125
< div className = "flex items-center justify-between mb-4" >
203
- { getStatusDisplay ( status , runStatus ) }
204
- < div className = "flex items-center gap-2 text-xs" >
205
- < span > Usage: </ span >
206
- < span > { tokenStats . total } </ span >
207
- < div className = "flex items-center gap-2" >
208
- < div className = "flex items-center gap-1" >
209
- < ArrowLeft className = "h-3 w-3" />
210
- < span > { tokenStats . input } </ span >
211
- </ div >
212
- < div className = "flex items-center gap-1" >
213
- < ArrowRightFromLine className = "h-3 w-3" />
214
- < span > { tokenStats . output } </ span >
215
- </ div >
216
- </ div >
217
- </ div >
126
+ < StatusDisplay chatStatus = { status } errorMessage = { actualRun ?. error_message || selectedRun ?. error_message } />
127
+ < TokenStatsDisplay stats = { tokenStats } />
218
128
</ div >
219
129
220
130
< form onSubmit = { handleSendMessage } >
@@ -235,9 +145,11 @@ export default function ChatInterface({ selectedTeamId, selectedRun, onNewSessio
235
145
</ Button >
236
146
) }
237
147
238
- { ( runStatus === "complete" || runStatus === "error" || runStatus === "stopped" ) && onNewSession && (
239
- < Button onClick = { onNewSession } className = "bg-violet-500 hover:bg-violet-600" type = "button" >
148
+ { ( runStatus === "complete" || runStatus === "error" || runStatus === "stopped" ) && (
149
+ < Button className = "bg-violet-500 hover:bg-violet-600" asChild >
150
+ < Link href = { `/agents/${ selectedTeamId } /chat` } >
240
151
Start New Chat
152
+ </ Link >
241
153
</ Button >
242
154
) }
243
155
0 commit comments