| 1 | package agent |
| 2 | |
| 3 | import ( |
| 4 | "slices" |
| 5 | |
| 6 | "reasonix/internal/provider" |
| 7 | ) |
| 8 | |
| 9 | // activeTurnKeepRounds is how many of the active turn's newest assistant |
| 10 | // rounds stay verbatim when an overflow forces a fold inside the turn. |
| 11 | const activeTurnKeepRounds = 2 |
| 12 | |
| 13 | // activeTurnFoldBoundary returns where an overflow rescue may end its fold |
| 14 | // inside the active turn: after the prompt and every completed round except |
| 15 | // the newest keep rounds, on a replay-safe unit boundary. A turn with too few |
| 16 | // rounds to split returns active, keeping the whole turn verbatim. |
| 17 | func activeTurnFoldBoundary(msgs []provider.Message, active, end int) int { |
| 18 | if active < 0 || end <= active+1 || end > len(msgs) { |
| 19 | return active |
| 20 | } |
| 21 | body := msgs[active+1 : end] |
| 22 | keep := activeTurnKeepRounds |
| 23 | for _, unit := range slices.Backward(extractMessageUnits(body)) { |
| 24 | if body[unit.lo].Role != provider.RoleAssistant { |
| 25 | continue |
| 26 | } |
| 27 | keep-- |
| 28 | if keep < 0 { |
| 29 | return active + 1 + unit.hi |
| 30 | } |
| 31 | } |
| 32 | return active |
| 33 | } |
| 34 |