From d956d3e2c470072182e57d5639a948b1c64670a2 Mon Sep 17 00:00:00 2001 From: Tyler Longwell Date: Tue, 12 May 2026 20:30:35 -0400 Subject: [PATCH] fix: skip empty assistant turns instead of placeholder space MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to #559. Instead of emitting a ' ' placeholder for empty assistant turns, skip them entirely. An assistant turn with no text and no tool calls carries zero information — no tool_use means no tool_result pairing constraint, so omitting is safe. This matches the canonical pattern used by litellm, goose, and other Anthropic API consumers: strip empty content at serialization time. --- crates/sprout-agent/src/llm.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/sprout-agent/src/llm.rs b/crates/sprout-agent/src/llm.rs index 5aa91275..82b0c803 100644 --- a/crates/sprout-agent/src/llm.rs +++ b/crates/sprout-agent/src/llm.rs @@ -127,9 +127,11 @@ fn anthropic_body(cfg: &Config, history: &[HistoryItem], tools: &[ToolDef]) -> V "name": c.name, "input": c.arguments })); } if content.is_empty() { - // Anthropic requires non-empty content arrays AND rejects - // empty text blocks. A single space satisfies both. - content.push(json!({ "type": "text", "text": " " })); + // Empty assistant turn (no text, no tool calls) — skip it. + // Anthropic rejects empty text blocks, and a placeholder + // just defers the problem. No tool_use = no pairing + // constraint, so omitting is safe. + continue; } messages.push(json!({ "role": "assistant", "content": content })); }