@@ -89,6 +89,11 @@ interface ParsedMessage {
89
89
value ?: number ;
90
90
visits ?: number ;
91
91
} ;
92
+ trajectory ?: Array < {
93
+ natural_language_description : string ;
94
+ action : string ;
95
+ feedback ?: string ;
96
+ } > ;
92
97
}
93
98
94
99
interface PathStep {
@@ -112,10 +117,14 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
112
117
onSessionIdChange,
113
118
variant = 'default'
114
119
} ) => {
120
+ const prevMessagesLengthRef = React . useRef ( messages . length ) ;
121
+
115
122
useEffect ( ( ) => {
116
- if ( messagesEndRef ?. current ) {
123
+ // Only scroll if new messages were added
124
+ if ( messages . length > prevMessagesLengthRef . current && messagesEndRef ?. current ) {
117
125
messagesEndRef . current . scrollIntoView ( { behavior : 'smooth' } ) ;
118
126
}
127
+ prevMessagesLengthRef . current = messages . length ;
119
128
} , [ messages , messagesEndRef ] ) ;
120
129
121
130
useEffect ( ( ) => {
@@ -133,6 +142,13 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
133
142
} , [ messages , onSessionIdChange ] ) ;
134
143
135
144
const getCardStyle = ( type : string ) => {
145
+ // Ignore tree update messages
146
+ if ( type === 'tree_update_node_expansion' ||
147
+ type === 'tree_update_node_evaluation' ||
148
+ type === 'tree_update_node_children_evaluation' ) {
149
+ return "hidden" ;
150
+ }
151
+
136
152
switch ( type ) {
137
153
// System Status Messages
138
154
case 'reflection_backtracking' :
@@ -243,6 +259,13 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
243
259
} ;
244
260
245
261
const getIcon = ( message : ParsedMessage ) => {
262
+ // Ignore tree update messages
263
+ if ( message . type === 'tree_update_node_expansion' ||
264
+ message . type === 'tree_update_node_evaluation' ||
265
+ message . type === 'tree_update_node_children_evaluation' ) {
266
+ return null ;
267
+ }
268
+
246
269
switch ( message . type ) {
247
270
case 'reflection_backtracking' :
248
271
return < Brain className = "h-4 w-4 text-blue-500" /> ;
@@ -358,13 +381,40 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
358
381
case 'node_expansion_complete' :
359
382
return < CheckCircle className = "h-4 w-4 text-green-500" /> ;
360
383
case 'evaluation_start' :
361
- return < Brain className = "h-4 w-4 text-blue-500" /> ;
384
+ return (
385
+ < div className = "flex items-center gap-2 animate-fadeIn" >
386
+ < div className = "animate-slideIn" >
387
+ < div className = "text-amber-600 dark:text-amber-400" >
388
+ Starting node evaluation
389
+ </ div >
390
+ < div className = "text-xs text-slate-500 dark:text-slate-400" >
391
+ { message . node_info ?. description }
392
+ { message . node_info ?. action && message . node_info . action !== 'ROOT' && (
393
+ < span > | Action: { message . node_info . action } </ span >
394
+ ) }
395
+ </ div >
396
+ </ div >
397
+ </ div >
398
+ ) ;
362
399
case 'child_evaluated' :
363
- return < Star className = "h-4 w-4 text-amber-500" /> ;
400
+ return (
401
+ < div className = "flex items-center gap-2 animate-fadeIn" >
402
+ < div className = "animate-slideIn" >
403
+ < div className = "text-amber-600 dark:text-amber-400" >
404
+ Child node evaluated
405
+ </ div >
406
+ < div className = "text-xs text-slate-500 dark:text-slate-400" >
407
+ Node ID: { message . node_id } | Score: { message . score ?. toFixed ( 3 ) }
408
+ </ div >
409
+ </ div >
410
+ </ div >
411
+ ) ;
364
412
case 'node_evaluation_start' :
365
- return < Brain className = "h-4 w-4 text-blue -500" /> ;
413
+ return < Brain className = "h-4 w-4 text-amber -500" /> ;
366
414
case 'node_evaluation_complete' :
367
- return < CheckCircle className = "h-4 w-4 text-green-500" /> ;
415
+ return < CheckCircle className = "h-4 w-4 text-amber-500" /> ;
416
+ case 'child_evaluated' :
417
+ return < Star className = "h-4 w-4 text-amber-500" /> ;
368
418
default :
369
419
return < Info className = "h-4 w-4 text-slate-500" /> ;
370
420
}
@@ -499,7 +549,9 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
499
549
500
550
const formatMessageContent = ( message : ParsedMessage ) => {
501
551
// Ignore tree update messages
502
- if ( message . type === 'tree_update_node_expansion' || message . type === 'tree_update_node_evaluation' ) {
552
+ if ( message . type === 'tree_update_node_expansion' ||
553
+ message . type === 'tree_update_node_evaluation' ||
554
+ message . type === 'tree_update_node_children_evaluation' ) {
503
555
return null ;
504
556
}
505
557
@@ -652,7 +704,7 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
652
704
{ getIcon ( message ) }
653
705
< div className = "animate-slideIn" >
654
706
< div className = "text-emerald-600 dark:text-emerald-400" >
655
- Search Complete | Score: { message . score }
707
+ Search Complete | Score: { message . score ?. toFixed ( 3 ) }
656
708
</ div >
657
709
{ message . path && message . path . length > 0 && (
658
710
< div className = "mt-1" >
@@ -727,7 +779,7 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
727
779
{ getIcon ( message ) }
728
780
< div className = "animate-slideIn" >
729
781
< div className = "text-amber-600 dark:text-amber-400" >
730
- Simulation Result | Reward: { message . reward }
782
+ Simulation Result | Reward: { message . reward ?. toFixed ( 3 ) }
731
783
</ div >
732
784
{ message . terminal_node_description && (
733
785
< div className = "text-xs text-slate-500 dark:text-slate-400" >
@@ -819,11 +871,66 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
819
871
case 'evaluation_start' :
820
872
return `Starting evaluation of ${ message . children_count } children for node ${ message . node_id } ` ;
821
873
case 'child_evaluated' :
822
- return `Child node ${ message . node_id } evaluated with score ${ message . score } ` ;
874
+ return `Child node ${ message . node_id } evaluated with score ${ message . score ?. toFixed ( 3 ) } ` ;
823
875
case 'node_evaluation_start' :
824
- return `Starting evaluation of node ${ message . node_id } ` ;
876
+ return (
877
+ < div className = "flex items-center gap-2 animate-fadeIn" >
878
+ < div className = "animate-slideIn" >
879
+ < div className = "text-amber-600 dark:text-amber-400" >
880
+ Starting node evaluation
881
+ </ div >
882
+ < div className = "text-xs text-slate-500 dark:text-slate-400" >
883
+ { message . node_info ?. description }
884
+ { message . node_info ?. action && message . node_info . action !== 'ROOT' && (
885
+ < span > | Action: { message . node_info . action } </ span >
886
+ ) }
887
+ </ div >
888
+ </ div >
889
+ </ div >
890
+ ) ;
825
891
case 'node_evaluation_complete' :
826
- return `Node ${ message . node_id } evaluated with score ${ message . score } ` ;
892
+ return (
893
+ < div className = "flex items-center gap-2 animate-fadeIn" >
894
+ < div className = "animate-slideIn" >
895
+ < div className = "text-amber-600 dark:text-amber-400 font-medium" >
896
+ Node evaluation complete
897
+ </ div >
898
+ < div className = "text-xs text-slate-500 dark:text-slate-400 mt-1" >
899
+ { message . node_info ?. description }
900
+ { message . node_info ?. action && message . node_info . action !== 'ROOT' && (
901
+ < span > | Action: { message . node_info . action } </ span >
902
+ ) }
903
+ </ div >
904
+ < div className = "text-xs font-medium text-amber-600 dark:text-amber-400 mt-2" >
905
+ Score: { message . score ?. toFixed ( 3 ) }
906
+ </ div >
907
+ { message . trajectory && message . trajectory . length > 0 && (
908
+ < div className = "mt-2 pl-2 border-l-2 border-amber-200 dark:border-amber-800" >
909
+ < div className = "text-xs font-medium text-amber-600 dark:text-amber-400 mb-1" >
910
+ Trajectory:
911
+ </ div >
912
+ { message . trajectory . map ( ( step , index ) => (
913
+ < div
914
+ key = { index }
915
+ className = "flex items-start gap-1 text-xs text-slate-500 dark:text-slate-400 animate-fadeIn mb-1.5"
916
+ style = { { animationDelay : `${ index * 100 } ms` } }
917
+ >
918
+ < ArrowRight className = "h-3 w-3 mt-0.5 flex-shrink-0" />
919
+ < div className = "flex-1" >
920
+ < div className = "font-medium" > { step . natural_language_description } </ div >
921
+ { step . feedback && (
922
+ < div className = "text-slate-400 italic mt-0.5" >
923
+ Feedback: { step . feedback }
924
+ </ div >
925
+ ) }
926
+ </ div >
927
+ </ div >
928
+ ) ) }
929
+ </ div >
930
+ ) }
931
+ </ div >
932
+ </ div >
933
+ ) ;
827
934
828
935
default :
829
936
return (
@@ -838,17 +945,22 @@ const MessageLogPanel: React.FC<MessageLogPanelProps> = ({
838
945
} ;
839
946
840
947
return (
841
- < div className = { `bg-white dark:bg-slate-800 rounded-lg shadow-md border border-slate-200 dark:border-slate-700 p-2 mt-3 ${ variant === 'mcts' ? 'border-cyan-500' : variant === 'lats' ? 'border-purple-500' : '' } ` } >
842
- < h2 className = "text-base font-semibold mb-1.5 text-sky-950 dark:text-sky-100 flex items-center" >
843
- < svg xmlns = "http://www.w3.org/2000/svg" className = "h-4 w-4 mr-1.5 text-cyan-500" viewBox = "0 0 20 20" fill = "currentColor" >
844
- < path fillRule = "evenodd" d = "M18 10c0 3.866-3.582 7-8 7a8.841 8.841 0 01-4.083-.98L2 17l1.338-3.123C2.493 12.767 2 11.434 2 10c0-3.866 3.582-7 8-7s8 3.134 8 7zM7 9H5v2h2V9zm8 0h-2v2h2V9zM9 9h2v2H9V9z" clipRule = "evenodd" />
845
- </ svg >
948
+ < div className = { `bg-white dark:bg-slate-800 rounded-lg shadow-md border border-slate-200 dark:border-slate-700 p-2 ${ variant === 'mcts' ? 'border-cyan-500' : variant === 'lats' ? 'border-purple-500' : '' } ` } >
949
+ < h2 className = "text-lg font-semibold text-sky-950 dark:text-sky-100 flex items-center mb-2" >
950
+ < MessageSquare className = "h-4 w-4 mr-1.5 text-primary" />
846
951
Message Log { variant !== 'default' ? `(${ variant . toUpperCase ( ) } )` : '' }
847
952
</ h2 >
848
953
< div className = "h-[150px] overflow-y-auto border border-slate-200 dark:border-slate-700 rounded-md p-1.5 bg-gradient-to-r from-sky-50 to-white dark:from-slate-900 dark:to-slate-800" >
849
954
{ messages . map ( ( msg , index ) => {
850
955
const parsedMessage = parseMessage ( msg . content ) ;
851
956
957
+ // Skip tree update messages
958
+ if ( parsedMessage . type === 'tree_update_node_expansion' ||
959
+ parsedMessage . type === 'tree_update_node_evaluation' ||
960
+ parsedMessage . type === 'tree_update_node_children_evaluation' ) {
961
+ return null ;
962
+ }
963
+
852
964
return (
853
965
< div
854
966
key = { index }
0 commit comments