Single source of truth for the `context.undo` backward walk, shared by both * projection modes. Mirrors agent-core `undo` (`agent/context/index.ts`): walk * from the end, skip `origin.kind === 'injection'` (those are KEPT even when * they sit inside the undo window), stop at `origin.kind === '
( messages: readonly ProjectedMessage[], count: number, )
| 680 | * undo marker (no removal). Defining the skip/stop predicate exactly once here |
| 681 | * keeps the two modes from drifting. */ |
| 682 | function computeUndoCutoff( |
| 683 | messages: readonly ProjectedMessage[], |
| 684 | count: number, |
| 685 | ): { cutoff: number; removedMessageCount: number } { |
| 686 | let removedUserCount = 0; |
| 687 | let removedMessageCount = 0; |
| 688 | let cutoff = messages.length; |
| 689 | for (let i = messages.length - 1; i >= 0; i--) { |
| 690 | const origin = messages[i]?.message.origin; |
| 691 | if (origin?.kind === 'injection') continue; // skip, keep |
| 692 | if (origin?.kind === 'compaction_summary') break; // stop |
| 693 | removedMessageCount++; |
| 694 | cutoff = i; |
| 695 | if (isRealUserInput(messages[i]!.message) && ++removedUserCount >= count) break; |
| 696 | } |
| 697 | return { cutoff, removedMessageCount }; |
| 698 | } |
no test coverage detected