Skip to content

Python: Feat: Add finish_reason support to AgentResponse and AgentResponseUpdate - #5211

Merged
Eduard van Valkenburg (eavanvalkenburg) merged 8 commits into
microsoft:mainfrom
LEDazzio01:feature/agent-response-finish-reason-v2
Apr 16, 2026
Merged

Python: Feat: Add finish_reason support to AgentResponse and AgentResponseUpdate#5211
Eduard van Valkenburg (eavanvalkenburg) merged 8 commits into
microsoft:mainfrom
LEDazzio01:feature/agent-response-finish-reason-v2

Conversation

@LEDazzio01

Copy link
Copy Markdown
Contributor

Add finish_reason to AgentResponse and AgentResponseUpdate

Motivation

Resolves the gap between ChatResponse/ChatResponseUpdate (which already have finish_reason) and the agent-level response types. This brings the Python SDK into parity with the .NET SDK's AgentResponseItem.FinishReason field.\n\nRelated: Supersedes #4958 (rebased cleanly from current main to resolve merge conflicts).\n\n## Changes\n\n### python/packages/core/agent_framework/_types.py\n\n1. AgentResponse.__init__ — Added finish_reason: FinishReasonLiteral | FinishReason | None = None parameter and self.finish_reason initialization.\n2. AgentResponseUpdate.__init__ — Same addition.\n3. _process_update() — Added an AgentResponse/AgentResponseUpdate isinstance block to propagate finish_reason from updates to the accumulated response (mirrors the existing ChatResponse block).\n4. map_chat_to_agent_update() — Forwards finish_reason from ChatResponseUpdate to AgentResponseUpdate.\n\n### python/packages/core/tests/core/test_finish_reason.py (NEW)\n\nComprehensive unit tests covering:\n- AgentResponse and AgentResponseUpdate initialization with finish_reason\n- map_chat_to_agent_update forwarding\n- _process_update propagation (including None-safety)\n- Serialization round-trip via .to_dict()\n\n## Testing\n\n- [x] All new tests pass locally\n- [x] No changes to existing public API signatures (additive only)\n- [x] Backward compatible — finish_reason defaults to None\n\n## Checklist\n\n- [x] Followed Contribution Guidelines\n- [x] Unit tests added\n- [x] No breaking changes"

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds finish_reason support to agent-level response types in the Python SDK, aligning AgentResponse/AgentResponseUpdate with the existing chat response types and improving parity with the .NET SDK.

Changes:

  • Added finish_reason fields to AgentResponse and AgentResponseUpdate.
  • Propagated finish_reason during streaming update accumulation (_process_update) and when mapping ChatResponseUpdate -> AgentResponseUpdate.
  • Added unit tests validating initialization, mapping, propagation behavior, and serialization.

Reviewed changes

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

File Description
python/packages/core/agent_framework/_types.py Adds finish_reason to agent response types and ensures it is propagated during update processing and chat→agent update mapping.
python/packages/core/tests/core/test_finish_reason.py New tests covering finish_reason initialization, propagation, and serialization for agent response types.

Comment thread python/packages/core/tests/core/test_finish_reason.py Outdated
Comment thread python/packages/core/agent_framework/_types.py
Comment thread python/packages/core/agent_framework/_types.py
Comment thread python/packages/core/tests/core/test_finish_reason.py Outdated
@eavanvalkenburg

Copy link
Copy Markdown
Member

and please rebase from main, there is a conflict

@LEDazzio01

Copy link
Copy Markdown
Contributor Author

Eduard van Valkenburg (@eavanvalkenburg) Done — both items addressed:

  1. Rebased onto latest main — conflict in _types.py resolved (kept upstream's modelmodel_id rename alongside the finish_reason propagation logic).

  2. Moved tests into test_types.py — deleted the separate test_finish_reason.py file and added all 7 test functions to the test_types.py file under a new # region finish_reason section. Added _process_update and map_chat_to_agent_update to the existing _types import block.

Comment thread python/packages/core/agent_framework/_types.py Outdated
@moonbox3

Evan Mattson (moonbox3) commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/core/agent_framework
   _types.py10908792%58, 67–68, 122, 127, 146, 148, 152, 156, 158, 160, 162, 180, 184, 210, 232, 237, 242, 246, 276, 687–688, 847–848, 1233, 1305, 1340, 1360, 1370, 1422, 1554–1556, 1738, 1841–1846, 1871, 1965, 1973–1975, 1980, 2071, 2083, 2106, 2361, 2385, 2484, 2738, 2947, 3020, 3031, 3033–3037, 3039, 3042–3050, 3060, 3130, 3265, 3270, 3275, 3280, 3284, 3368–3370, 3399, 3476–3480
TOTAL27693320188% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
5610 20 💤 0 ❌ 0 🔥 1m 30s ⏱️

@moonbox3

Copy link
Copy Markdown
Contributor

L. Elaine Dazzio (@LEDazzio01) lint is failing in core

@LEDazzio01

Copy link
Copy Markdown
Contributor Author

Evan Mattson (@moonbox3) Fixed in d29c620 — the SIM102 lint error in _process_update() has been resolved by combining the nested if statements. Also addressed Eduard van Valkenburg (@eavanvalkenburg)'s review feedback (model_idmodel) in 3130827.

@eavanvalkenburg

Copy link
Copy Markdown
Member

Another fail, please run the same checks locally. Uv run poe typing -P core

@LEDazzio01

Copy link
Copy Markdown
Contributor Author

Eduard van Valkenburg (@eavanvalkenburg) Fixed in c134789 — the pyright reportArgumentType error in map_chat_to_agent_update() was caused by pyright widening FinishReason (a NewType of str) back to plain str when reading the attribute. Added a # type: ignore[arg-type] matching the existing pattern used throughout _types.py.

Ran uv run poe typing -P core locally — mypy passes clean, pyright has zero _types.py errors (only pre-existing observability.py import errors remain).

Add finish_reason field to AgentResponse and AgentResponseUpdate classes,
propagate it through _process_update() and map_chat_to_agent_update(),
and add comprehensive unit tests.

Fixes #4622
…back

Move all finish_reason test cases from the separate test_finish_reason.py
file into test_types.py as requested by eavanvalkenburg. Tests are placed
in a new '# region finish_reason' section at the end of the file.
Address PR review feedback from @eavanvalkenburg — ChatResponse and
ChatResponseUpdate both use 'model', not 'model_id'.
Combine nested if statements for AgentResponse finish_reason check
to satisfy ruff SIM102 rule, with line wrapping to stay under 120 chars.
Add type: ignore[arg-type] for FinishReason NewType widening when
passing ChatResponseUpdate.finish_reason to AgentResponseUpdate.
Matches existing patterns in the codebase (40+ similar ignores).
github-merge-queue Bot pushed a commit that referenced this pull request Apr 16, 2026
…ponseUpdate (#5211)

* feat: add finish_reason support to AgentResponse and AgentResponseUpdate

Add finish_reason field to AgentResponse and AgentResponseUpdate classes,
propagate it through _process_update() and map_chat_to_agent_update(),
and add comprehensive unit tests.

Fixes #4622

* feat: add finish_reason to AgentResponse and AgentResponseUpdate

* style: add copyright header to test_finish_reason.py

* docs: add finish_reason to AgentResponse and AgentResponseUpdate docstrings

* refactor: move finish_reason tests into test_types.py per review feedback

Move all finish_reason test cases from the separate test_finish_reason.py
file into test_types.py as requested by eavanvalkenburg. Tests are placed
in a new '# region finish_reason' section at the end of the file.

* fix: use model instead of model_id in _process_update

Address PR review feedback from @eavanvalkenburg — ChatResponse and
ChatResponseUpdate both use 'model', not 'model_id'.

* fix: resolve SIM102 lint error in _process_update

Combine nested if statements for AgentResponse finish_reason check
to satisfy ruff SIM102 rule, with line wrapping to stay under 120 chars.

* fix: resolve pyright reportArgumentType in map_chat_to_agent_update

Add type: ignore[arg-type] for FinishReason NewType widening when
passing ChatResponseUpdate.finish_reason to AgentResponseUpdate.
Matches existing patterns in the codebase (40+ similar ignores).
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Apr 16, 2026
Merged via the queue into microsoft:main with commit 91e3435 Apr 16, 2026
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants