@@ -114,6 +114,37 @@ function buildLongConversation(numExchanges: number, resultLength = 5_000) {
114114 return out
115115}
116116
117+ function buildParallelToolConversation (
118+ numBatches : number ,
119+ batchSize : number ,
120+ resultLength = 5_000 ,
121+ ) {
122+ const out : Array < { role : string ; content : unknown } > = [
123+ { role : 'user' , content : 'start the parallel work' } ,
124+ ]
125+ for ( let batch = 0 ; batch < numBatches ; batch ++ ) {
126+ const firstId = batch * batchSize
127+ out . push ( {
128+ role : 'assistant' ,
129+ content : Array . from ( { length : batchSize } , ( _ , offset ) => ( {
130+ type : 'tool_use' ,
131+ id : `toolu_${ firstId + offset } ` ,
132+ name : 'Read' ,
133+ input : { file_path : `/path/to/file${ firstId + offset } .ts` } ,
134+ } ) ) ,
135+ } )
136+ out . push ( {
137+ role : 'user' ,
138+ content : Array . from ( { length : batchSize } , ( _ , offset ) => ( {
139+ type : 'tool_result' ,
140+ tool_use_id : `toolu_${ firstId + offset } ` ,
141+ content : bigText ( resultLength ) ,
142+ } ) ) ,
143+ } )
144+ }
145+ return out
146+ }
147+
117148function makeFakeResponse ( ) : Response {
118149 return new Response (
119150 JSON . stringify ( {
@@ -537,12 +568,12 @@ test('Responses compression preserves structured history and materially reduces
537568 expect ( compressedByCallId . get ( 'toolu_0' ) ) . toBe (
538569 '[Old tool result content cleared]' ,
539570 )
540- for ( let i = 1 ; i <= 14 ; i ++ ) {
571+ for ( let i = 1 ; i <= 15 ; i ++ ) {
541572 expect ( compressedByCallId . get ( `toolu_${ i } ` ) ) . toMatch (
542573 / ^ \[ R e a d a r g s = .* c h a r s o m i t t e d \] $ / ,
543574 )
544575 }
545- for ( let i = 15 ; i <= 24 ; i ++ ) {
576+ for ( let i = 16 ; i <= 24 ; i ++ ) {
546577 expect ( compressedByCallId . get ( `toolu_${ i } ` ) ) . toContain ( '[…truncated' )
547578 }
548579 expect ( compressedByCallId . get ( 'toolu_16_extra' ) ) . toContain ( '[…truncated' )
@@ -571,6 +602,38 @@ test('Responses compression preserves structured history and materially reduces
571602 expect ( compressedSize ) . toBeLessThan ( uncompressedSize * 0.5 )
572603} )
573604
605+ test ( 'Responses compression assigns tiers per parallel tool result' , async ( ) => {
606+ mockState . enabled = true
607+ mockState . effectiveWindow = 100_000
608+ const messages = buildParallelToolConversation ( 5 , 6 )
609+
610+ const body = await captureResponsesRequestBody ( messages , MID_TIER_MODEL )
611+ const functionCalls = getResponsesFunctionCalls ( body )
612+ const functionOutputs = getResponsesFunctionOutputs ( body )
613+ const outputs = new Map (
614+ functionOutputs . map ( item => [ item . call_id , item . output ?? '' ] ) ,
615+ )
616+
617+ expect ( functionCalls ) . toHaveLength ( 30 )
618+ expect ( functionOutputs ) . toHaveLength ( 30 )
619+ expect ( functionCalls . map ( item => item . call_id ) ) . toEqual (
620+ functionOutputs . map ( item => item . call_id ) ,
621+ )
622+ for ( let i = 0 ; i < 15 ; i ++ ) {
623+ expect ( outputs . get ( `toolu_${ i } ` ) ) . toMatch (
624+ / ^ \[ R e a d a r g s = .* 5 0 0 0 c h a r s o m i t t e d \] $ / ,
625+ )
626+ }
627+ for ( let i = 15 ; i < 25 ; i ++ ) {
628+ expect ( outputs . get ( `toolu_${ i } ` ) ) . toContain (
629+ '[…truncated 3000 chars from tool history]' ,
630+ )
631+ }
632+ for ( let i = 25 ; i < 30 ; i ++ ) {
633+ expect ( outputs . get ( `toolu_${ i } ` ) ) . toHaveLength ( 5_000 )
634+ }
635+ } )
636+
574637test ( 'Responses compression preserves structured parts while compressing old and mid text' , async ( ) => {
575638 mockState . enabled = true
576639 mockState . effectiveWindow = 100_000
@@ -767,7 +830,7 @@ test('non-chat transports do not invoke the Chat message converter', () => {
767830 expect ( selectMessages ( 'chat_completions' , ( ) => chatMessages ) ) . toBe ( chatMessages )
768831} )
769832
770- test ( 'Anthropic and Gemini transports do not invoke tool history compression' , ( ) => {
833+ test ( 'only OpenAI-compatible transports invoke tool history compression' , ( ) => {
771834 const selectMessages = __test . getCompressedMessagesForTransport
772835 const rawMessages = [ { role : 'user' , content : 'hello' } ]
773836 const compressedMessages = [ { role : 'user' , content : 'compressed' } ]
@@ -779,6 +842,7 @@ test('Anthropic and Gemini transports do not invoke tool history compression', (
779842
780843 expect ( selectMessages ( 'anthropic_messages' , rawMessages , compress ) ) . toBe ( rawMessages )
781844 expect ( selectMessages ( 'gemini' , rawMessages , compress ) ) . toBe ( rawMessages )
845+ expect ( selectMessages ( 'future_transport' , rawMessages , compress ) ) . toBe ( rawMessages )
782846 expect ( compressionCalls ) . toBe ( 0 )
783847
784848 expect ( selectMessages ( 'responses' , rawMessages , compress ) ) . toBe ( compressedMessages )
0 commit comments