anchorUserMessage guarantees the packed window carries a user-role message whenever history has one. The newest-first walk drops oldest-first, so a long single turn (one task message, then dozens of assistant+tool rounds that fill the budget) evicts the sole user task and hands the backend a userles
(kept, history []Message)
| 199 | // path already make. A lone user message carries no tool-call pairing, so this is |
| 200 | // safe after the dangling/orphan passes. No-op when a recent user already |
| 201 | // survived (normal multi-turn) or history has no user message at all. |
| 202 | func anchorUserMessage(kept, history []Message) []Message { |
| 203 | for _, m := range kept { |
| 204 | if m.Role == RoleUser { |
| 205 | return kept |
| 206 | } |
| 207 | } |
| 208 | for i := range history { |
| 209 | if history[i].Role == RoleUser { |
| 210 | return append([]Message{history[i]}, kept...) |
| 211 | } |
| 212 | } |
| 213 | return kept |
| 214 | } |
| 215 | |
| 216 | // demoteSystemMessages rewrites every system-role message in the packed history |