Strip Grok harness wrappers from a user prompt. Grok's agent runtime delivers the human message inside an XML-ish envelope: ```text Make sure this project runs. ``` Atomic records that string as the turn's change message, so `atomic log` would show the tags. Extract the inner text when the envelope is present; leave plain prompts untouched.
(prompt: &str)
| 309 | /// would show the tags. Extract the inner text when the envelope is present; |
| 310 | /// leave plain prompts untouched. |
| 311 | fn normalize_user_prompt(prompt: &str) -> String { |
| 312 | let trimmed = prompt.trim(); |
| 313 | |
| 314 | // Prefer a complete open/close pair (multiline body supported). |
| 315 | const OPEN: &str = "<user_query>"; |
| 316 | const CLOSE: &str = "</user_query>"; |
| 317 | if let Some(start) = trimmed.find(OPEN) { |
| 318 | let after_open = &trimmed[start + OPEN.len()..]; |
| 319 | if let Some(end) = after_open.find(CLOSE) { |
| 320 | return after_open[..end].trim().to_string(); |
| 321 | } |
| 322 | // Open tag without close — take everything after the open tag. |
| 323 | return after_open.trim().to_string(); |
| 324 | } |
| 325 | |
| 326 | trimmed.to_string() |
| 327 | } |
| 328 | |
| 329 | fn with_xai_provider(mut raw: Value) -> Value { |
| 330 | if let Some(obj) = raw.as_object_mut() { |