chore: Bump version to 0.1.4

- Fix: Skip empty/whitespace text content blocks
- Fix: Validate function call arguments and skip malformed calls
- Fix: Skip outputs for skipped function calls to maintain consistency
- Resolves Anthropic API errors:
  - "messages: text content blocks must contain non-whitespace text"
  - "Extra data: line 1 column 26 (char 25)" (invalid JSON)
  - "unexpected `tool_use_id` found in `tool_result` blocks"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-14 19:52:13 +01:00
parent 866ca2a372
commit 67ff31104f
12 changed files with 70 additions and 52 deletions

View File

@@ -161,6 +161,9 @@ pub(crate) async fn stream_chat_completions(
// aggregated assistant message was recorded alongside an earlier partial).
let mut last_assistant_text: Option<String> = None;
// Track call_ids of skipped function calls so we can also skip their outputs
let mut skipped_call_ids: std::collections::HashSet<String> = std::collections::HashSet::new();
for (idx, item) in input.iter().enumerate() {
match item {
ResponseItem::Message { role, content, .. } => {
@@ -227,6 +230,15 @@ pub(crate) async fn stream_chat_completions(
call_id,
..
} => {
// Validate that arguments is valid JSON before sending to API
// If invalid, skip this function call to avoid API errors
if serde_json::from_str::<serde_json::Value>(arguments).is_err() {
debug!("Skipping malformed function call with invalid JSON arguments: {}", arguments);
// Track this call_id so we can also skip its corresponding output
skipped_call_ids.insert(call_id.clone());
continue;
}
let mut msg = json!({
"role": "assistant",
"content": null,
@@ -271,6 +283,12 @@ pub(crate) async fn stream_chat_completions(
messages.push(msg);
}
ResponseItem::FunctionCallOutput { call_id, output } => {
// Skip outputs for function calls that were skipped due to malformed arguments
if skipped_call_ids.contains(call_id) {
debug!("Skipping function call output for skipped call_id: {}", call_id);
continue;
}
// Prefer structured content items when available (e.g., images)
// otherwise fall back to the legacy plain-string content.
let content_value = if let Some(items) = &output.content_items {