assistant2: Handle empty tool results by providing placeholder text (#27130)

Agus Zubiaga created

This is surprising, but the Anthropic API returns a 400 if a tool output
is an empty string because it thinks we're attaching a `tool use`
without a corresponding `tool result`, but we are not, it's just empty
(which seems totally reasonable) 🙃

Release Notes:

- N/A

Change summary

crates/assistant2/src/tool_use.rs | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)

Detailed changes

crates/assistant2/src/tool_use.rs 🔗

@@ -309,9 +309,19 @@ impl ToolUseState {
         if let Some(tool_uses) = self.tool_uses_by_user_message.get(&message_id) {
             for tool_use_id in tool_uses {
                 if let Some(tool_result) = self.tool_results.get(tool_use_id) {
-                    request_message
-                        .content
-                        .push(MessageContent::ToolResult(tool_result.clone()));
+                    request_message.content.push(MessageContent::ToolResult(
+                        LanguageModelToolResult {
+                            tool_use_id: tool_use_id.clone(),
+                            is_error: tool_result.is_error,
+                            content: if tool_result.content.is_empty() {
+                                // Surprisingly, the API fails if we return an empty string here.
+                                // It thinks we are sending a tool use without a tool result.
+                                "<Tool returned an empty string>".into()
+                            } else {
+                                tool_result.content.clone()
+                            },
+                        },
+                    ));
                 }
             }
         }