Skip to content

Python: Parse fenced JSON from the group chat orchestrator agent - #8850

Merged
Eduard van Valkenburg (eavanvalkenburg) merged 2 commits into
microsoft:mainfrom
ShivamSharma43:fix/8814-group-chat-fenced-json
Oct 2, 2026
Merged

Eduard van Valkenburg (eavanvalkenburg) merged 2 commits into
microsoft:mainfrom
ShivamSharma43:fix/8814-group-chat-fenced-json

Conversation

@ShivamSharma43

Copy link
Copy Markdown
Contributor

Motivation & Context

AgentBasedGroupChatOrchestrator asks the orchestrator agent for an AgentOrchestrationOutput via response_format. Providers that don't honor response_format (for example Claude on Bedrock through an OpenAI-compatible Chat Completions endpoint) return the JSON as plain text wrapped in a Markdown code fence. _parse_agent_output can't decode fenced JSON, so the orchestration decision, including terminate: true, is never applied and the group chat runs until max_rounds.

Description & Review Guide

  • What are the major changes?
    • _parse_agent_output now also tries the body of the last Markdown code fence (```json, a bare ```, or any language tag) as a parse candidate.
    • Fenced candidates are appended after the raw text, so responses that already parsed, including the concatenated-JSON stop-gap, behave exactly as before.
    • New tests: an end-to-end group chat whose manager returns fenced JSON and terminates on it, a parametrized parser test covering fence variants (language tag, bare fence, uppercase tag with CRLF, single-line fence, prose before the fence), and a check that fenced non-JSON still raises the same ValueError.
  • What is the impact of these changes? Group chats with an orchestrator agent on providers that ignore response_format now honor the manager's decisions instead of degrading to max_rounds. No public API changes.
  • What do you want reviewers to focus on? Whether using the last fenced block is the right choice when a response contains several (this matches the existing "last JSON object" behavior of _parse_last_json_object).

This covers suggested fix (1) from the issue. Fixes (2), exposing retry_attempts on GroupChatBuilder, and (3), documentation, are left for separate changes.

Related Issue

Fixes #8814

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 is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • 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 any language prefix) — a workflow keeps the label and title prefix in sync automatically.

🤖 Generated with Claude Code

When a provider ignores response_format, the orchestrator agent can return
its AgentOrchestrationOutput as JSON wrapped in a Markdown code fence. The
parser rejected it, so terminate=true was never applied and the group chat
ran until max_rounds.

_parse_agent_output now also tries the body of the last fenced block as a
parse candidate, after the raw text, so existing behavior is unchanged.

Fixes microsoft#8814

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@agent-framework-automation agent-framework-automation Bot added the python Usage: [Issues, PRs], Target: Python label Sep 29, 2026
Comment thread python/packages/orchestrations/agent_framework_orchestrations/_group_chat.py Outdated
Comment thread python/packages/orchestrations/agent_framework_orchestrations/_group_chat.py Outdated
@eavanvalkenburg

Copy link
Copy Markdown
Member

/review

@github-actions github-actions Bot 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.

MAF Automated Review — Iteration 1

Result: Findings reported
Scope: full PR (1 commit(s)): 780d5b320174
Model: gpt-5.6-sol

Overview

The change preserves structured and raw JSON precedence, validates every extracted candidate through the existing Pydantic contract, and adds end-to-end coverage for common fenced responses. The fallback still fails for MIME-style fence tags, and its backtracking regex can synchronously stall the event loop on malformed model output. Both risks are confined to text-fallback responses but can prevent the manager decision from being applied.

Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
2 verified findings remained after source verification (2 medium) across 1 file. Details are attached to the affected lines below.

Affected areas: python/packages/orchestrations/agent_framework_orchestrations/_group_chat.py

Comment thread python/packages/orchestrations/agent_framework_orchestrations/_group_chat.py Outdated
Comment thread python/packages/orchestrations/agent_framework_orchestrations/_group_chat.py Outdated
…ntic

Replace the group chat fence regex with extract_markdown_fence_bodies in
_orchestrator_helpers.py, which both group chat and Magentic's _extract_json
now use.

- A closing fence must be at least as long as the opening one and end its
  line, so backticks inside a JSON string value (for example a fenced code
  block in final_message) no longer end the block, and an outer fence may
  use four or more backticks.
- The whole info string is consumed, so MIME tags such as application/json
  parse.
- The scan never backtracks, so an unterminated fence followed by
  whitespace no longer stalls the event loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merged via the queue into microsoft:main with commit bbb639e Oct 2, 2026
44 checks passed

This branch was previously deployed

1 inactive deployment
github-app-auth — 9e7aacb2 Deployed Oct 1, 2026 by ShivamSharma43 via add_label #24216
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.

Python: [Bug]: AgentBasedGroupChatOrchestrator drops terminate=true when the manager returns Markdown-fenced JSON

4 participants