@@ -133,6 +133,22 @@ export function splitMessagesByTokenShare(
133133 let currentTokens = 0 ;
134134
135135 let pendingToolCallIds = new Set < string > ( ) ;
136+ let pendingChunkStartIndex : number | null = null ;
137+
138+ const splitCurrentAtPendingBoundary = ( ) : boolean => {
139+ if (
140+ pendingChunkStartIndex === null ||
141+ pendingChunkStartIndex <= 0 ||
142+ chunks . length >= normalizedParts - 1
143+ ) {
144+ return false ;
145+ }
146+ chunks . push ( current . slice ( 0 , pendingChunkStartIndex ) ) ;
147+ current = current . slice ( pendingChunkStartIndex ) ;
148+ currentTokens = current . reduce ( ( sum , msg ) => sum + estimateCompactionMessageTokens ( msg ) , 0 ) ;
149+ pendingChunkStartIndex = 0 ;
150+ return true ;
151+ } ;
136152
137153 for ( const message of messages ) {
138154 const messageTokens = estimateCompactionMessageTokens ( message ) ;
@@ -146,6 +162,7 @@ export function splitMessagesByTokenShare(
146162 chunks . push ( current ) ;
147163 current = [ ] ;
148164 currentTokens = 0 ;
165+ pendingChunkStartIndex = null ;
149166 }
150167
151168 current . push ( message ) ;
@@ -154,14 +171,15 @@ export function splitMessagesByTokenShare(
154171 if ( message . role === "assistant" ) {
155172 const toolCalls = extractToolCallsFromAssistant ( message ) ;
156173 const stopReason = ( message as { stopReason ?: unknown } ) . stopReason ;
157- pendingToolCallIds =
158- stopReason === "aborted" || stopReason === "error"
159- ? new Set ( )
160- : new Set ( toolCalls . map ( ( t ) => t . id ) ) ;
174+ const keepsPending =
175+ stopReason !== "aborted" && stopReason !== "error" && toolCalls . length > 0 ;
176+ pendingToolCallIds = keepsPending ? new Set ( toolCalls . map ( ( t ) => t . id ) ) : new Set ( ) ;
177+ pendingChunkStartIndex = keepsPending ? current . length - 1 : null ;
161178 } else if ( message . role === "toolResult" && pendingToolCallIds . size > 0 ) {
162179 const resultId = extractToolResultId ( message ) ;
163180 if ( ! resultId ) {
164181 pendingToolCallIds = new Set ( ) ;
182+ pendingChunkStartIndex = null ;
165183 } else {
166184 pendingToolCallIds . delete ( resultId ) ;
167185 }
@@ -173,10 +191,15 @@ export function splitMessagesByTokenShare(
173191 chunks . push ( current ) ;
174192 current = [ ] ;
175193 currentTokens = 0 ;
194+ pendingChunkStartIndex = null ;
176195 }
177196 }
178197 }
179198
199+ if ( pendingToolCallIds . size > 0 && currentTokens > targetTokens ) {
200+ splitCurrentAtPendingBoundary ( ) ;
201+ }
202+
180203 if ( current . length > 0 ) {
181204 chunks . push ( current ) ;
182205 }
0 commit comments