@@ -36,6 +36,51 @@ interface TraceInsightData {
3636 insightName : InsightName ;
3737}
3838
39+ class GroupedConsoleMessage {
40+ readonly key : string ;
41+ #first: ConsoleFormatter ;
42+ #count = 0 ;
43+ #msgids: number [ ] = [ ] ;
44+
45+ constructor ( first : ConsoleFormatter ) {
46+ this . #first = first ;
47+ this . key = GroupedConsoleMessage . keyFor ( first ) ;
48+ this . add ( first ) ;
49+ }
50+
51+ static keyFor ( message : ConsoleFormatter ) : string {
52+ const json = message . toJSON ( ) ;
53+ return JSON . stringify ( {
54+ type : json . type ,
55+ text : json . text ,
56+ argsCount : json . argsCount ,
57+ } ) ;
58+ }
59+
60+ add ( message : ConsoleFormatter ) : void {
61+ const json = message . toJSON ( ) ;
62+ this . #count++ ;
63+ this . #msgids. push ( json . id ) ;
64+ }
65+
66+ toString ( ) : string {
67+ const base = this . #first. toString ( ) ;
68+ if ( this . #count <= 1 ) {
69+ return base ;
70+ }
71+ return `${ base } [${ this . #count} times]` ;
72+ }
73+
74+ toJSON ( ) : object {
75+ const base = this . #first. toJSON ( ) ;
76+ return {
77+ ...base ,
78+ count : this . #count,
79+ msgids : this . #msgids,
80+ } ;
81+ }
82+ }
83+
3984export class McpResponse implements Response {
4085 #includePages = false ;
4186 #snapshotParams?: SnapshotParams ;
@@ -612,7 +657,7 @@ Call ${handleDialog.name} to handle it before continuing.`);
612657 }
613658
614659 if ( this . #consoleDataOptions?. include ) {
615- const messages = data . consoleMessages ?? [ ] ;
660+ const messages = this . #groupConsoleMessages ( data . consoleMessages ?? [ ] ) ;
616661
617662 response . push ( '## Console messages' ) ;
618663 if ( messages . length ) {
@@ -650,6 +695,41 @@ Call ${handleDialog.name} to handle it before continuing.`);
650695 } ;
651696 }
652697
698+ #groupConsoleMessages(
699+ messages : Array < ConsoleFormatter | IssueFormatter > ,
700+ ) : Array < ConsoleFormatter | IssueFormatter | GroupedConsoleMessage > {
701+ const result : Array < ConsoleFormatter | IssueFormatter | GroupedConsoleMessage > = [ ] ;
702+
703+ let activeGroup : GroupedConsoleMessage | null = null ;
704+
705+ const flush = ( ) => {
706+ if ( activeGroup ) {
707+ result . push ( activeGroup ) ;
708+ activeGroup = null ;
709+ }
710+ } ;
711+
712+ for ( const message of messages ) {
713+ if ( ! ( message instanceof ConsoleFormatter ) ) {
714+ flush ( ) ;
715+ result . push ( message ) ;
716+ continue ;
717+ }
718+
719+ const key = GroupedConsoleMessage . keyFor ( message ) ;
720+ if ( activeGroup && activeGroup . key === key ) {
721+ activeGroup . add ( message ) ;
722+ continue ;
723+ }
724+
725+ flush ( ) ;
726+ activeGroup = new GroupedConsoleMessage ( message ) ;
727+ }
728+
729+ flush ( ) ;
730+ return result ;
731+ }
732+
653733 #dataWithPagination< T > ( data : T [ ] , pagination ?: PaginationOptions ) {
654734 const response = [ ] ;
655735 const paginationResult = paginate < T > ( data , pagination ) ;
0 commit comments