Skip to content

fix: Hugging Face output items yield a tool-result - #306

Closed
cunninghamcard-bit wants to merge 1 commit into
fix/hugging-face-mcp-calls-are-not-dynamicfrom
fix/hugging-face-output-items-yield-a-tool-result
Closed

cunninghamcard-bit wants to merge 1 commit into
fix/hugging-face-mcp-calls-are-not-dynamicfrom
fix/hugging-face-output-items-yield-a-tool-result

Conversation

@cunninghamcard-bit

Copy link
Copy Markdown
Contributor

Summary

Before: a non-streaming Hugging Face function_call item with an output gave only the tool-call; the output was dropped. An mcp_call whose output was an empty string still gave a tool-result.

After: both follow upstream's if (part.output): a non-empty output string adds a tool-result holding that string, an empty or missing one adds nothing. The stream's function_call uses the same check.

Found while porting the upstream Hugging Face tests (#303, case tool calls › should handle function call tool responses). Part of the #276 list. Stacked on #305 (CHANGELOG lines touch); the stream-error PR follows.

How it works today

HuggingFaceResponsesModel::do_generate                 aimux-providers/src/huggingface/responses.rs:163
└─ build_generate_content(&response)                   responses.rs:933                     // upstream: huggingface-responses-language-model.ts:220
   ├─ "function_call"                                   responses.rs:995                     // upstream: case 'function_call' :304
   │  └─ RawToolCall only                                                                     //   if (part.output) push tool-result { result: part.output } :312
   └─ "mcp_call"                                        responses.rs:1013                    // upstream: case 'mcp_call' :264
      └─ if part.get("output") is not null → ToolResult { result: output.clone() }   :1030   //   if (part.output) :273   ('' is false)
HuggingFaceResponsesModel::do_stream → transform_event  responses.rs:306
└─ output_item.done › "function_call"                   responses.rs:422
   └─ if output is a string → ToolResult               :450                                 // upstream: if (value.item.output) :489

What this PR changes

build_generate_content                                 responses.rs:931
├─ "function_call"   if let Some(output) = non_empty_output(part)    :1010   ← new ToolResult { result: Value::String(output) }
└─ "mcp_call"        if let Some(output) = non_empty_output(part)    :1040   ← empty string gives no tool-result
transform_event › output_item.done › "function_call"
   if let Some(output) = non_empty_output(item)        :449
non_empty_output(part) -> Option<&str>                 :1087   ← `part.output` when JavaScript reads it as true: a non-empty string

Tests (tests/huggingface_responses_test.rs): should_handle_function_call_tool_responses asserted the dropped output; it now expects tool-call, tool-result, text. mcp_call_with_empty_output_has_no_tool_result is new. The full upstream case is in #303.

Docs: CHANGELOG Fixed.

Type of change

  • Bug fix (non-breaking)
  • New feature (non-breaking)
  • Breaking change
  • New provider
  • New / updated binding
  • Docs / RFC

Checklist

  • cargo +1.99 fmt -p aimux-providers -- --check passes
  • cargo +1.99 clippy -p aimux-providers --lib --tests -- -D warnings passes
  • cargo +1.99 test -p aimux-providers --test huggingface_responses_test passes (33)
  • scripts/check_provider_boundaries.sh passes
  • Updated relevant docs (CHANGELOG)
  • Commit messages follow Conventional Commits

Notes for reviewers

The mcp_call result is now always the output string (upstream's result: part.output); before, a non-string JSON output was passed through as is.


Generated by Claude Code

…ggingface@2.0.62

doGenerate pushes a tool-result after a function_call or mcp_call when
part.output is truthy, with the output string as the result
(huggingface-responses-language-model.ts:273, :312). aimux dropped the
function_call output and, for mcp_call, also gave a tool-result for an
empty string. Both now follow `if (part.output)`, and so does the
stream's function_call (:489).

Tests: should_handle_function_call_tool_responses now expects the
tool-result; mcp_call_with_empty_output_has_no_tool_result is new
(tests/huggingface_responses_test.rs).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5
cunninghamcard-bit added a commit that referenced this pull request Oct 20, 2026
The three behaviour fixes now live in their own PRs (#305, #306, #307);
this branch stacks on the last one. responses.rs and CHANGELOG.md are the
same on both sides; the old test file keeps the markers and takes the
two aimux tests the fix PRs added.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoxcKU4zBD64Lri3e4Lrq5

Copy link
Copy Markdown
Contributor Author

Folded into #307 together with the other Hugging Face fixes, so each vendor has one fix PR. This change is commit fcdc9c0a there. Closing this one; the branch stays as it is.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant