@@ -35,7 +35,7 @@ describe("MessageQueue", () => {
3535 expect ( queue . getDisplayText ( ) ) . toBe ( "/compact -t 3000" ) ;
3636 } ) ;
3737
38- it ( "should return rawCommand even with multiple messages if last has compaction metadata " , ( ) => {
38+ it ( "should show all messages when compaction is added after normal message " , ( ) => {
3939 queue . add ( "First message" ) ;
4040
4141 const metadata : MuxFrontendMetadata = {
@@ -51,8 +51,8 @@ describe("MessageQueue", () => {
5151
5252 queue . add ( "Summarize this conversation..." , options ) ;
5353
54- // Should use rawCommand from latest options
55- expect ( queue . getDisplayText ( ) ) . toBe ( "/compact" ) ;
54+ // Should show all messages: first message + compaction rawCommand
55+ expect ( queue . getDisplayText ( ) ) . toBe ( "First message\n /compact" ) ;
5656 } ) ;
5757
5858 it ( "should return joined messages when metadata type is not compaction-request" , ( ) => {
@@ -116,6 +116,67 @@ describe("MessageQueue", () => {
116116 } ) ;
117117 } ) ;
118118
119+ describe ( "multi-message batching" , ( ) => {
120+ it ( "should batch multiple follow-up messages" , ( ) => {
121+ queue . add ( "First message" ) ;
122+ queue . add ( "Second message" ) ;
123+ queue . add ( "Third message" ) ;
124+
125+ expect ( queue . getMessages ( ) ) . toEqual ( [ "First message" , "Second message" , "Third message" ] ) ;
126+ expect ( queue . getDisplayText ( ) ) . toBe ( "First message\nSecond message\nThird message" ) ;
127+ } ) ;
128+
129+ it ( "should batch follow-up message after compaction" , ( ) => {
130+ const metadata : MuxFrontendMetadata = {
131+ type : "compaction-request" ,
132+ rawCommand : "/compact" ,
133+ parsed : { } ,
134+ } ;
135+
136+ queue . add ( "Summarize..." , {
137+ model : "claude-3-5-sonnet-20241022" ,
138+ muxMetadata : metadata ,
139+ } ) ;
140+ queue . add ( "And then do this follow-up task" ) ;
141+
142+ // Display shows slash command for compaction, then the follow-up
143+ expect ( queue . getDisplayText ( ) ) . toBe ( "/compact\nAnd then do this follow-up task" ) ;
144+ // Raw messages have the actual prompt
145+ expect ( queue . getMessages ( ) ) . toEqual ( [ "Summarize..." , "And then do this follow-up task" ] ) ;
146+ } ) ;
147+
148+ it ( "should produce combined message for API call" , ( ) => {
149+ queue . add ( "First message" , { model : "gpt-4" } ) ;
150+ queue . add ( "Second message" ) ;
151+
152+ const { message, options } = queue . produceMessage ( ) ;
153+
154+ // Messages are joined with newlines
155+ expect ( message ) . toBe ( "First message\nSecond message" ) ;
156+ // Latest options are used
157+ expect ( options ?. model ) . toBe ( "gpt-4" ) ;
158+ } ) ;
159+
160+ it ( "should batch messages with mixed images" , ( ) => {
161+ const image1 = { url : "data:image/png;base64,abc" , mediaType : "image/png" } ;
162+ const image2 = { url : "data:image/jpeg;base64,def" , mediaType : "image/jpeg" } ;
163+
164+ queue . add ( "Message with image" , { model : "gpt-4" , imageParts : [ image1 ] } ) ;
165+ queue . add ( "Follow-up without image" ) ;
166+ queue . add ( "Another with image" , { model : "gpt-4" , imageParts : [ image2 ] } ) ;
167+
168+ expect ( queue . getMessages ( ) ) . toEqual ( [
169+ "Message with image" ,
170+ "Follow-up without image" ,
171+ "Another with image" ,
172+ ] ) ;
173+ expect ( queue . getImageParts ( ) ) . toEqual ( [ image1 , image2 ] ) ;
174+ expect ( queue . getDisplayText ( ) ) . toBe (
175+ "Message with image\nFollow-up without image\nAnother with image"
176+ ) ;
177+ } ) ;
178+ } ) ;
179+
119180 describe ( "getImageParts" , ( ) => {
120181 it ( "should return accumulated images from multiple messages" , ( ) => {
121182 const image1 = {
0 commit comments