Python: avoid empty function-limit fallback responses#5809
Conversation
f71dd5e to
5a2cb19
Compare
Python Test Coverage Report •
Python Unit Test Overview
|
||||||||||||||||||||||||||||||
| def _response_has_contents(response: ChatResponse[Any]) -> bool: | ||
| for message in response.messages: | ||
| for content in message.contents: | ||
| if getattr(content, "type", None) != "text": |
There was a problem hiding this comment.
Should this ignore tool/control-plane content instead? In max_function_calls or error-limit path, _process_function_requests prepends prior function call/result messages before this check, so those non-text contents can suppress fallback while final assistant response is still empty. Could callers still get blank output for the limit case this PR is trying to fix?
|
Addressed the review in 37f5261. The function-limit fallback now ignores function/tool/control-plane content when deciding whether a final response exists, so preserved function call/result history no longer suppresses the fallback. I also changed the fallback path to append the final assistant message when existing tool history is present. Validation: targeted pytest for the empty final response cases, ruff check, ruff format --check, py_compile, mypy on _tools.py, and git diff --check. |
37f5261 to
1aa39ae
Compare
|
Rebased this branch onto current main and force-pushed with lease. Re-ran the focused function-limit validation after the rebase: the three empty/fallback regression tests passed, ruff check passed, ruff format --check passed, mypy on _tools.py passed, py_compile passed, and git diff --check passed. |
Fixes #5769.
When the function invocation loop reaches a configured limit, the SDK asks the model for one final no-tool response. Some providers can still return an empty assistant message for that fallback, which leaves callers with a blank final answer even though the limit handling worked.
This adds a narrow guard for that limit path only: if the final no-tool response is empty, return a deterministic assistant message explaining that function invocation stopped after hitting the configured limit. Normal non-empty fallback responses are left unchanged.
To verify
Ran locally from
python/packages/core:uv run pytest tests/core/test_function_invocation_logic.py -q -p no:cacheprovider --basetemp .tmp\pytest-fulluv run ruff check agent_framework\_tools.py tests\core\test_function_invocation_logic.pyuv run ruff format --check agent_framework\_tools.py tests\core\test_function_invocation_logic.pyuv run pyright agent_framework\_tools.py tests\core\test_function_invocation_logic.pyAlso ran from the repo root:
python -m py_compile python\packages\core\agent_framework\_tools.py python\packages\core\tests\core\test_function_invocation_logic.pygit diff --check