Skip to content

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

Merged
eavanvalkenburg merged 8 commits intomicrosoft:mainfrom
LEDazzio01:feature/agent-response-finish-reason-v2
Apr 16, 2026
Merged

Python: Feat: Add finish_reason support to AgentResponse and AgentResponseUpdate#5211
eavanvalkenburg merged 8 commits intomicrosoft: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"

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

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 LEDazzio01 force-pushed the feature/agent-response-finish-reason-v2 branch from 3447c14 to e19fc57 Compare April 15, 2026 22:34
@LEDazzio01
Copy link
Copy Markdown
Contributor Author

@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
Copy link
Copy Markdown
Contributor

moonbox3 commented Apr 16, 2026

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

@LEDazzio01 lint is failing in core

@LEDazzio01
Copy link
Copy Markdown
Contributor Author

@moonbox3 Fixed in d29c620 — the SIM102 lint error in _process_update() has been resolved by combining the nested if statements. Also addressed @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

@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).

LEDazzio01 and others added 8 commits April 16, 2026 13:40
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 microsoft#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).
@eavanvalkenburg eavanvalkenburg force-pushed the feature/agent-response-finish-reason-v2 branch from c134789 to 197a918 Compare April 16, 2026 11:40
@eavanvalkenburg eavanvalkenburg added this pull request to the merge queue Apr 16, 2026
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
@eavanvalkenburg eavanvalkenburg added this pull request to the merge queue 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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants