@@ -38,9 +38,8 @@ import {
38
38
} from "./TorchAgentPage/styles" ;
39
39
import { TodoList } from "./TorchAgentPage/TodoList" ;
40
40
import { ToolUse } from "./TorchAgentPage/ToolUse" ;
41
- import { ParsedContent } from "./TorchAgentPage/types " ;
41
+ import { useMessageProcessor } from "./TorchAgentPage/useMessageProcessor " ;
42
42
import {
43
- extractGrafanaLinks ,
44
43
formatElapsedTime ,
45
44
formatTokenCount ,
46
45
renderMarkdownWithLinks ,
@@ -54,7 +53,13 @@ interface ChatSession {
54
53
filename : string ;
55
54
key : string ;
56
55
title ?: string ;
56
+ displayedTitle ?: string ;
57
57
status ?: string ;
58
+ shared ?: {
59
+ uuid : string ;
60
+ sharedAt : string ;
61
+ shareUrl : string ;
62
+ } ;
58
63
}
59
64
60
65
// Helper function to check for special auth cookie (presence only)
@@ -69,7 +74,17 @@ const hasAuthCookie = () => {
69
74
return ! ! authCookie ;
70
75
} ;
71
76
72
- export const TorchAgentPage = ( ) => {
77
+ interface TorchAgentPageProps {
78
+ initialChatData ?: any ;
79
+ isSharedView ?: boolean ;
80
+ shareId ?: string ;
81
+ }
82
+
83
+ export const TorchAgentPage = ( {
84
+ initialChatData,
85
+ isSharedView = false ,
86
+ shareId,
87
+ } : TorchAgentPageProps = { } ) => {
73
88
const session = useSession ( ) ;
74
89
const theme = useTheme ( ) ;
75
90
const isMobile = useMediaQuery ( theme . breakpoints . down ( "lg" ) ) ; // Below 1200px
@@ -91,8 +106,16 @@ export const TorchAgentPage = () => {
91
106
92
107
const [ query , setQuery ] = useState ( "" ) ;
93
108
const [ isLoading , setIsLoading ] = useState ( false ) ;
94
- const [ response , setResponse ] = useState ( "" ) ;
95
- const [ parsedResponses , setParsedResponses ] = useState < ParsedContent [ ] > ( [ ] ) ;
109
+
110
+ // Use message processor hook for handling chat data
111
+ const messageProcessor = useMessageProcessor ( ) ;
112
+ const {
113
+ parsedResponses,
114
+ response,
115
+ setParsedResponses,
116
+ setResponse,
117
+ processSessionData,
118
+ } = messageProcessor ;
96
119
const [ expandedTools , setExpandedTools ] = useState < Record < number , boolean > > (
97
120
{ }
98
121
) ;
@@ -116,6 +139,11 @@ export const TorchAgentPage = () => {
116
139
const [ isSessionLoading , setIsSessionLoading ] = useState ( false ) ;
117
140
const [ drawerOpen , setDrawerOpen ] = useState ( true ) ;
118
141
const [ headerHeight , setHeaderHeight ] = useState ( 80 ) ; // Default fallback
142
+ const [ currentSessionSharedInfo , setCurrentSessionSharedInfo ] = useState < {
143
+ uuid : string ;
144
+ sharedAt : string ;
145
+ shareUrl : string ;
146
+ } | null > ( null ) ;
119
147
120
148
const contentRef = useRef < HTMLDivElement > ( null ) ;
121
149
@@ -263,59 +291,11 @@ export const TorchAgentPage = () => {
263
291
if ( response . ok ) {
264
292
const sessionData = await response . json ( ) ;
265
293
266
- if ( sessionData . messages && Array . isArray ( sessionData . messages ) ) {
267
- setParsedResponses ( [ ] ) ;
268
-
269
- let fullResponse = "" ;
270
- sessionData . messages . forEach ( ( msg : any ) => {
271
- if ( msg . content ) {
272
- fullResponse += msg . content + "\n" ;
273
- }
274
- } ) ;
275
- setResponse ( fullResponse ) ;
276
-
277
- // Process all messages in chronological order
278
- sessionData . messages . forEach ( ( msg : any ) => {
279
- if ( msg . type === "user_message" || msg . type === "user" ) {
280
- // Process user message
281
- const textContent = msg . content ;
282
- const grafanaLinks = extractGrafanaLinks ( textContent ) ;
283
-
284
- setParsedResponses ( ( prev ) => [
285
- ...prev ,
286
- {
287
- type : "user_message" ,
288
- content : textContent ,
289
- displayedContent : textContent ,
290
- isAnimating : false ,
291
- timestamp : Date . now ( ) ,
292
- grafanaLinks :
293
- grafanaLinks . length > 0 ? grafanaLinks : undefined ,
294
- } ,
295
- ] ) ;
296
- } else if ( msg . content ) {
297
- // Process assistant message content line by line
298
- const lines = msg . content
299
- . split ( "\n" )
300
- . filter ( ( line : string ) => line . trim ( ) ) ;
301
- lines . forEach ( ( line : string ) => {
302
- processMessageLine (
303
- line ,
304
- setParsedResponses ,
305
- false ,
306
- undefined ,
307
- ( sessionId : string ) => {
308
- console . log (
309
- "Setting session ID from loadChatSession:" ,
310
- sessionId
311
- ) ;
312
- setCurrentSessionId ( sessionId ) ;
313
- }
314
- ) ;
315
- } ) ;
316
- }
317
- } ) ;
318
- }
294
+ // Update shared info for current session
295
+ setCurrentSessionSharedInfo ( sessionData . shared || null ) ;
296
+
297
+ // Process session data using the message processor
298
+ processSessionData ( sessionData , setCurrentSessionId ) ;
319
299
320
300
setSelectedSession ( sessionId ) ;
321
301
setCurrentSessionId ( sessionId ) ;
@@ -345,6 +325,7 @@ export const TorchAgentPage = () => {
345
325
setParsedResponses ( [ ] ) ;
346
326
setSelectedSession ( null ) ;
347
327
setCurrentSessionId ( null ) ;
328
+ setCurrentSessionSharedInfo ( null ) ;
348
329
setError ( "" ) ;
349
330
setTotalTokens ( 0 ) ;
350
331
setCompletedTokens ( 0 ) ;
@@ -729,7 +710,20 @@ export const TorchAgentPage = () => {
729
710
730
711
const hasCookieAuth = hasAuthCookie ( ) ;
731
712
732
- if ( session . status === "loading" || permissionState === "checking" ) {
713
+ // Initialize shared view data if provided
714
+ useEffect ( ( ) => {
715
+ if ( isSharedView && initialChatData ) {
716
+ console . log ( "Loading shared chat data:" , initialChatData ) ;
717
+ processSessionData ( initialChatData , setCurrentSessionId ) ;
718
+ setSelectedSession ( shareId || "shared" ) ;
719
+ setCurrentSessionId ( shareId || "shared" ) ;
720
+ }
721
+ } , [ isSharedView , initialChatData , shareId , processSessionData ] ) ;
722
+
723
+ if (
724
+ ! isSharedView &&
725
+ ( session . status === "loading" || permissionState === "checking" )
726
+ ) {
733
727
return (
734
728
< TorchAgentPageContainer >
735
729
< QuerySection sx = { { padding : "20px" , textAlign : "center" } } >
@@ -745,6 +739,7 @@ export const TorchAgentPage = () => {
745
739
}
746
740
747
741
if (
742
+ ! isSharedView &&
748
743
! hasCookieAuth &&
749
744
( session . status === "unauthenticated" ||
750
745
! session . data ?. user ||
@@ -804,6 +799,7 @@ export const TorchAgentPage = () => {
804
799
805
800
// Check if user is authenticated but has insufficient permissions
806
801
if (
802
+ ! isSharedView &&
807
803
session . data ?. user &&
808
804
! hasAuthCookie ( ) &&
809
805
permissionState === "insufficient"
@@ -1000,7 +996,7 @@ export const TorchAgentPage = () => {
1000
996
return (
1001
997
< Box sx = { { display : "flex" , height : "100vh" } } >
1002
998
{ /* Hamburger button for collapsed sidebar */ }
1003
- { ! drawerOpen && (
999
+ { ! isSharedView && ! drawerOpen && (
1004
1000
< Box
1005
1001
sx = { {
1006
1002
position : "fixed" ,
@@ -1024,22 +1020,25 @@ export const TorchAgentPage = () => {
1024
1020
</ Box >
1025
1021
) }
1026
1022
1027
- < ChatHistorySidebar
1028
- drawerOpen = { drawerOpen }
1029
- sidebarWidth = { sidebarWidth }
1030
- chatHistory = { chatHistory }
1031
- selectedSession = { selectedSession }
1032
- isHistoryLoading = { isHistoryLoading }
1033
- isMobile = { isMobile }
1034
- headerHeight = { headerHeight }
1035
- onStartNewChat = { startNewChat }
1036
- onLoadChatSession = { loadChatSession }
1037
- onToggleSidebar = { toggleSidebar }
1038
- />
1023
+ { ! isSharedView && (
1024
+ < ChatHistorySidebar
1025
+ drawerOpen = { drawerOpen }
1026
+ sidebarWidth = { sidebarWidth }
1027
+ chatHistory = { chatHistory }
1028
+ selectedSession = { selectedSession }
1029
+ isHistoryLoading = { isHistoryLoading }
1030
+ isMobile = { isMobile }
1031
+ headerHeight = { headerHeight }
1032
+ onStartNewChat = { startNewChat }
1033
+ onLoadChatSession = { loadChatSession }
1034
+ onToggleSidebar = { toggleSidebar }
1035
+ />
1036
+ ) }
1039
1037
1040
1038
< ChatMain
1041
1039
sx = { {
1042
- marginLeft : drawerOpen && ! isMobile ? `${ sidebarWidth } px` : 0 ,
1040
+ marginLeft :
1041
+ ! isSharedView && drawerOpen && ! isMobile ? `${ sidebarWidth } px` : 0 ,
1043
1042
transition : "margin-left 0.3s ease" ,
1044
1043
} }
1045
1044
>
@@ -1053,14 +1052,28 @@ export const TorchAgentPage = () => {
1053
1052
) : (
1054
1053
< TorchAgentPageContainer
1055
1054
ref = { contentRef }
1056
- drawerOpen = { drawerOpen && ! isMobile }
1055
+ drawerOpen = { ! isSharedView && drawerOpen && ! isMobile }
1057
1056
sidebarWidth = { sidebarWidth }
1058
1057
>
1059
1058
< HeaderSection
1060
1059
showScrollButton = { showScrollButton }
1061
1060
onScrollToBottom = { scrollToBottomAndEnable }
1062
1061
featureRequestUrl = { featureRequestUrl }
1063
1062
bugReportUrl = { bugReportUrl }
1063
+ currentSessionId = { currentSessionId }
1064
+ chatTitle = {
1065
+ selectedSession
1066
+ ? chatHistory . find (
1067
+ ( session ) => session . sessionId === selectedSession
1068
+ ) ?. displayedTitle ||
1069
+ chatHistory . find (
1070
+ ( session ) => session . sessionId === selectedSession
1071
+ ) ?. title ||
1072
+ "Current Chat"
1073
+ : "Current Chat"
1074
+ }
1075
+ isSharedView = { isSharedView }
1076
+ sharedInfo = { currentSessionSharedInfo }
1064
1077
/>
1065
1078
1066
1079
< ChatMessages ref = { chatContainerRef } >
@@ -1156,7 +1169,7 @@ export const TorchAgentPage = () => {
1156
1169
</ ChatMessages >
1157
1170
1158
1171
{ /* Show welcome message for completely new chats */ }
1159
- { ! selectedSession && (
1172
+ { ! isSharedView && ! selectedSession && (
1160
1173
< WelcomeSection
1161
1174
query = { query }
1162
1175
isLoading = { isLoading }
@@ -1169,7 +1182,7 @@ export const TorchAgentPage = () => {
1169
1182
) }
1170
1183
1171
1184
{ /* Show query input for active chats (read-only for history) */ }
1172
- { selectedSession && (
1185
+ { ! isSharedView && selectedSession && (
1173
1186
< QueryInputSection
1174
1187
query = { query }
1175
1188
isLoading = { isLoading }
@@ -1181,6 +1194,40 @@ export const TorchAgentPage = () => {
1181
1194
currentSessionId = { currentSessionId }
1182
1195
/>
1183
1196
) }
1197
+
1198
+ { /* Show shared view banner */ }
1199
+ { isSharedView && (
1200
+ < Box
1201
+ sx = { {
1202
+ p : 2 ,
1203
+ bgcolor : "primary.main" ,
1204
+ color : "primary.contrastText" ,
1205
+ textAlign : "center" ,
1206
+ borderRadius : 1 ,
1207
+ mb : 2 ,
1208
+ } }
1209
+ >
1210
+ < Typography variant = "body2" >
1211
+ This is a shared read-only chat. You can view the conversation
1212
+ but cannot interact with it.{ " " }
1213
+ < Typography
1214
+ component = "a"
1215
+ href = "/flambeau"
1216
+ sx = { {
1217
+ color : "primary.contrastText" ,
1218
+ textDecoration : "underline" ,
1219
+ fontWeight : "bold" ,
1220
+ "&:hover" : {
1221
+ textDecoration : "none" ,
1222
+ } ,
1223
+ } }
1224
+ >
1225
+ Click here to start a new chat
1226
+ </ Typography >
1227
+ .
1228
+ </ Typography >
1229
+ </ Box >
1230
+ ) }
1184
1231
</ TorchAgentPageContainer >
1185
1232
) }
1186
1233
</ ChatMain >
0 commit comments