Skip to content

Python: Fix empty final output after tool calls#5906

Open
VIVEKJAINDTU wants to merge 1 commit into
microsoft:mainfrom
VIVEKJAINDTU:fix/empty-terminal-response-after-tools
Open

Python: Fix empty final output after tool calls#5906
VIVEKJAINDTU wants to merge 1 commit into
microsoft:mainfrom
VIVEKJAINDTU:fix/empty-terminal-response-after-tools

Conversation

@VIVEKJAINDTU
Copy link
Copy Markdown

@VIVEKJAINDTU VIVEKJAINDTU commented May 16, 2026

Motivation and Context

After a successful tool call, some providers return a final assistant turn with no text, tool calls, or reasoning payload. The conversation shape looks like:

  • assistant → function call
  • tool → function result
  • assistant → empty contents

In that case response.text stays empty even though tools ran correctly, which breaks callers that rely on the final assistant message.

Fixes: #5726

Description

  • Skip empty assistant messages in the Chat Completions parser.
  • In the function-invocation loop, if tools ran but the final text is empty, make one more call with tool_choice="none" to get a text response.
  • Skip this fallback when middleware terminates the loop early (should_terminate).

Tests

Added test_base_client_with_function_calling_recovers_from_empty_terminal_response.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

Copilot AI review requested due to automatic review settings May 16, 2026 12:05
@github-actions github-actions Bot changed the title Fix empty final output after tool calls Python: Fix empty final output after tool calls May 16, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes cases where tool execution succeeds but the terminal assistant turn is empty, causing response.text / final_output to be "" and breaking callers that depend on a final assistant message.

Changes:

  • Update the OpenAI Chat Completions response parser to skip emitting empty assistant messages.
  • Add a function-invocation fallback: if tools ran and the terminal assistant text is empty, issue one more model call with tool_choice="none" to force a text response (unless middleware requested early termination).
  • Add a unit test covering recovery from an empty terminal assistant response after tool execution.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
python/packages/openai/agent_framework_openai/_chat_completion_client.py Skips emitting empty terminal assistant messages when parsing Chat Completions responses.
python/packages/core/agent_framework/_tools.py Adds a post-tools fallback call (tool_choice="none") to recover a final text response, and threads middleware termination state.
python/packages/core/tests/core/test_function_invocation_logic.py Adds a regression test for recovering from an empty terminal assistant message after tool execution.

Comment on lines +2450 to +2454
fallback_messages = (
list(prepped_messages) + list(response.messages)
if response.conversation_id is None
else []
)
Comment on lines +701 to +704
# Some providers may return a terminal choice with no text/tool payload.
# Skip emitting empty assistant messages to avoid empty final outputs.
if contents:
messages.append(Message(role="assistant", contents=contents))
@VIVEKJAINDTU
Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: Final output is empty after successful tool execution in declarative agent run

3 participants