Skip to content

Python: expose final-only loop responses in create_harness_agent - #10214

Merged
Eduard van Valkenburg (eavanvalkenburg) merged 2 commits into
microsoft:mainfrom
M-Hietala:m-hietala/10209_expose_final_answer_only_option_to_harness_agents
Nov 10, 2026
Merged

Eduard van Valkenburg (eavanvalkenburg) merged 2 commits into
microsoft:mainfrom
M-Hietala:m-hietala/10209_expose_final_answer_only_option_to_harness_agents

Conversation

@M-Hietala

Copy link
Copy Markdown
Member

Motivation & Context

Looping harness agents currently return an aggregated non-streaming response containing earlier answers and injected loop prompts. Applications that only need the final answer cannot select the existing AgentLoopMiddleware.return_final_only behavior through create_harness_agent().

This change exposes that option without changing the default behavior.

Description & Review Guide

  • What are the major changes?
    Add the optional, keyword-only loop_return_final_only: bool = False parameter to create_harness_agent() and its type stub. Forward it to AgentLoopMiddleware, document its behavior, and add regression coverage.

    from agent_framework import create_harness_agent, todos_remaining
    from agent_framework.openai import OpenAIChatClient
    
    client = OpenAIChatClient(model="gpt-4.1")
    
    # Existing behavior: aggregate iterations and injected prompts.
    aggregated = create_harness_agent(
        client=client,
        loop_should_continue=todos_remaining(),
    )
    
    # New opt-in behavior: return the final iteration's response.
    final_only = create_harness_agent(
        client=client,
        loop_should_continue=todos_remaining(),
        loop_return_final_only=True,
    )
  • What is the impact of these changes?
    Non-streaming callers can opt into final-only responses. The default remains False, preserving existing aggregation. Streaming updates and streaming finalization remain unchanged. The option is ignored when loop_should_continue is not configured. Middleware ordering and approval handling are unchanged.

    All 186 tests in the harness factory and loop modules passed, along with focused Ruff, Pyright, and mypy checks. The full core suite has not been run for this change.

  • What do you want reviewers to focus on?
    Runtime/stub signature consistency, unchanged defaults, forwarding to the existing middleware, and streaming parity. This follows the narrowly scoped factory-option proposal in Python: [Feature]: Option in create_harness_agent to return only the agent's answer from a looping run (result.text currently includes the loop's prompts) #10209; it does not change AgentResponse.text globally.

Related Issue

Fixes #10209

AI Assistance

  • No material AI assistance was used.
  • This is an AI-assisted contribution. I reviewed, understood, and verified all submitted content and accept responsibility for it.

AI assistance details: Copilot assisted with implementation, tests, documentation, focused validation, and this PR description.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR links to an agreed issue with no competing open PR, or the Related Issue section documents a trivial-change or repository-automation exception.
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after a language prefix) — a workflow keeps the label and title prefix in sync automatically.

Copilot AI balanced review requested due to automatic review settings November 9, 2026 20:15
@agent-framework-automation agent-framework-automation Bot added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python labels Nov 9, 2026

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.

🟡 Changes recommended

A raw 0x97 byte makes the test module invalid UTF-8, causing a SyntaxError that prevents pytest from collecting its tests.

1 open issue
What changed in this PR

Exposes the existing final-only loop response option through Python’s create_harness_agent(), addressing #10209 without changing default aggregation or streaming behavior.

Changes:

  • Adds keyword-only loop_return_final_only: bool = False to the factory and type stub, forwarding it to AgentLoopMiddleware.
  • Documents the option’s behavior and when it is ignored.
  • Adds regression coverage for non-streaming results, streaming behavior, and configuration without a loop.
File Description
python/​packages/​core/​tests/​core/​test_harness_agent.py Tests defaults, final-only responses, streaming parity, and ignored loop options.
python/​packages/​core/​AGENTS.md Documents the new harness loop option.
python/​packages/​core/​agent_framework/​_harness/​_agent.pyi Exposes the option in the typed factory signature.
python/​packages/​core/​agent_framework/​_harness/​_agent.py Adds, documents, and forwards the option to loop middleware.

Review effort: Balanced

Fix typo in comment regarding function call results.

Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Merged via the queue into microsoft:main with commit ee538ca Nov 10, 2026
51 checks passed

This branch was previously deployed

1 inactive deployment
github-app-auth — d02a3816 Deployed Nov 9, 2026 by M-Hietala via add_label #27433
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python

Projects

None yet

3 participants