Consumes the response stream until a valid [ToolUse] is parsed. The arguments are the fields from the first [ChatResponseStream::ToolUseEvent] consumed.
(&mut self, id: String, name: String)
| 466 | /// |
| 467 | /// The arguments are the fields from the first [ChatResponseStream::ToolUseEvent] consumed. |
| 468 | async fn parse_tool_use(&mut self, id: String, name: String) -> Result<AssistantToolUse, RecvError> { |
| 469 | let mut tool_string = String::new(); |
| 470 | let start = Instant::now(); |
| 471 | while let Some(ChatResponseStream::ToolUseEvent { .. }) = self.peek().await? { |
| 472 | if let Some(ChatResponseStream::ToolUseEvent { input, stop, .. }) = self.next().await? { |
| 473 | if let Some(i) = input { |
| 474 | tool_string.push_str(&i); |
| 475 | } |
| 476 | if let Some(true) = stop { |
| 477 | break; |
| 478 | } |
| 479 | } |
| 480 | } |
| 481 | |
| 482 | let args = match serde_json::from_str(&tool_string) { |
| 483 | Ok(args) => { |
| 484 | // Ensure we have a valid JSON object |
| 485 | match args { |
| 486 | serde_json::Value::Object(_) => args, |
| 487 | _ => { |
| 488 | error!("Received non-object JSON for tool arguments: {:?}", args); |
| 489 | let warning_args = serde_json::Value::Object( |
| 490 | [( |
| 491 | "key".to_string(), |
| 492 | serde_json::Value::String( |
| 493 | "WARNING: the actual tool use arguments were not a valid JSON object".to_string(), |
| 494 | ), |
| 495 | )] |
| 496 | .into_iter() |
| 497 | .collect(), |
| 498 | ); |
| 499 | self.tool_uses.push(AssistantToolUse { |
| 500 | id: id.clone(), |
| 501 | name: name.clone(), |
| 502 | orig_name: name.clone(), |
| 503 | args: warning_args.clone(), |
| 504 | orig_args: warning_args.clone(), |
| 505 | }); |
| 506 | let message = Box::new(AssistantMessage::new_tool_use( |
| 507 | Some(self.message_id.clone()), |
| 508 | std::mem::take(&mut self.assistant_text), |
| 509 | self.tool_uses.clone().into_iter().collect(), |
| 510 | )); |
| 511 | return Err(self.error(RecvErrorKind::ToolValidationError { |
| 512 | tool_use_id: id, |
| 513 | name, |
| 514 | message, |
| 515 | error_message: format!("Expected JSON object, got: {:?}", args), |
| 516 | })); |
| 517 | }, |
| 518 | } |
| 519 | }, |
| 520 | Err(err) if !tool_string.is_empty() => { |
| 521 | // If we failed deserializing after waiting for a long time, then this is most |
| 522 | // likely bedrock responding with a stop event for some reason without actually |
| 523 | // including the tool contents. Essentially, the tool was too large. |
| 524 | let time_elapsed = start.elapsed(); |
| 525 | let args = serde_json::Value::Object( |