Returns a split index that avoids orphaning retained tool responses. Retained events (tail of candidate events) may contain function responses. If their matching function call events are in the compacted prefix, contents assembly can fail. This method shifts the split earlier so matching func
(
*,
candidate_events: list[Event],
event_retention_size: int,
)
| 332 | |
| 333 | |
| 334 | def _safe_token_compaction_split_index( |
| 335 | *, |
| 336 | candidate_events: list[Event], |
| 337 | event_retention_size: int, |
| 338 | ) -> int: |
| 339 | """Returns a split index that avoids orphaning retained tool responses. |
| 340 | |
| 341 | Retained events (tail of candidate events) may contain function responses. |
| 342 | If their matching function call events are in the compacted prefix, contents |
| 343 | assembly can fail. This method shifts the split earlier so matching function |
| 344 | call events are retained together with their responses. |
| 345 | |
| 346 | Iterates backwards through candidate_events once, maintaining a running set |
| 347 | of unmatched response IDs. The latest valid split point where no unmatched |
| 348 | responses remain is returned. |
| 349 | """ |
| 350 | initial_split = len(candidate_events) - event_retention_size |
| 351 | if initial_split <= 0: |
| 352 | return 0 |
| 353 | |
| 354 | unmatched_response_ids: set[str] = set() |
| 355 | best_split = 0 |
| 356 | |
| 357 | for i in range(len(candidate_events) - 1, -1, -1): |
| 358 | event = candidate_events[i] |
| 359 | unmatched_response_ids.update(_event_function_response_ids(event)) |
| 360 | call_ids = _event_function_call_ids(event) |
| 361 | unmatched_response_ids -= call_ids |
| 362 | |
| 363 | if not unmatched_response_ids and i <= initial_split: |
| 364 | best_split = i |
| 365 | break |
| 366 | |
| 367 | return best_split |
| 368 | |
| 369 | |
| 370 | async def _run_compaction_for_token_threshold_config( |
no test coverage detected