Convert [`ToolMessage`] list into OpenAI's messages array.
(messages: &[ToolMessage])
| 468 | |
| 469 | /// Convert [`ToolMessage`] list into OpenAI's messages array. |
| 470 | fn openai_messages(messages: &[ToolMessage]) -> Vec<serde_json::Value> { |
| 471 | let mut out = Vec::new(); |
| 472 | for msg in messages { |
| 473 | match msg { |
| 474 | ToolMessage::System { content } => { |
| 475 | out.push(json!({ "role": "system", "content": content })); |
| 476 | } |
| 477 | ToolMessage::User { content } => { |
| 478 | out.push(json!({ "role": "user", "content": content })); |
| 479 | } |
| 480 | ToolMessage::Assistant { |
| 481 | content, |
| 482 | tool_calls, |
| 483 | } => { |
| 484 | if tool_calls.is_empty() { |
| 485 | out.push(json!({ "role": "assistant", "content": content })); |
| 486 | } else { |
| 487 | let tcs: Vec<serde_json::Value> = tool_calls |
| 488 | .iter() |
| 489 | .map(|tc| { |
| 490 | json!({ |
| 491 | "id": tc.id, |
| 492 | "type": "function", |
| 493 | "function": { |
| 494 | "name": tc.name, |
| 495 | "arguments": serde_json::to_string(&tc.arguments) |
| 496 | .unwrap_or_else(|_| "{}".to_string()), |
| 497 | } |
| 498 | }) |
| 499 | }) |
| 500 | .collect(); |
| 501 | let mut m = json!({ |
| 502 | "role": "assistant", |
| 503 | "tool_calls": tcs, |
| 504 | }); |
| 505 | if !content.is_empty() { |
| 506 | m["content"] = json!(content); |
| 507 | } |
| 508 | out.push(m); |
| 509 | } |
| 510 | } |
| 511 | ToolMessage::ToolResult { |
| 512 | tool_call_id, |
| 513 | content, |
| 514 | .. |
| 515 | } => { |
| 516 | out.push(json!({ |
| 517 | "role": "tool", |
| 518 | "tool_call_id": tool_call_id, |
| 519 | "content": content, |
| 520 | })); |
| 521 | } |
| 522 | } |
| 523 | } |
| 524 | out |
| 525 | } |
| 526 | |
| 527 | // ── Agentic loop ──────────────────────────────────────────────── |