demoteSystemMessages rewrites every system-role message in the packed history to a user message. buildMessages always prepends the embedded system prompt as wire element 0, so any system message Pack returns is a SECOND, non-leading system message, which strict OpenAI-compat backends reject outright
(kept []Message)
| 225 | // legal everywhere. Must run AFTER anchorUserMessage: a demoted nudge would |
| 226 | // otherwise masquerade as a surviving user message and suppress the original-task |
| 227 | // anchor. Mutates only the copied kept slice, never history. |
| 228 | func demoteSystemMessages(kept []Message) []Message { |
| 229 | for i := range kept { |
| 230 | if kept[i].Role == RoleSystem { |
| 231 | kept[i].Role = RoleUser |
| 232 | } |
| 233 | } |
| 234 | return kept |
| 235 | } |
| 236 | |
| 237 | // newestToolGroup returns the assistant that issued the newest tool result |