Repository navigation
Python: Support response_format in GitHubCopilotAgent - #9810
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Structured-output parsing can incorrectly use trailing subagent text instead of the root answer, while mapping schemas and aliased models can trigger serialization or validation failures.
3 open issues
What changed in this PR
Adds opt-in structured output support to GitHubCopilotAgent, bringing it closer to other Agent Framework providers and addressing #9809.
Changes:
- Accepts Pydantic models or JSON Schema mappings through
response_format. - Forwards schemas to streaming and non-streaming SDK calls, excludes them from session creation, and enables
AgentResponse.valueparsing. - Adds tests for schema forwarding, default options, unstructured requests, and streaming results.
| File | Description |
|---|---|
python/packages/github_copilot/tests/test_github_copilot_agent.py |
Adds structured-output tests for both response modes. |
python/packages/github_copilot/agent_framework_github_copilot/_agent.py |
Adds the option, SDK forwarding, and structured response parsing. |
Review effort: Balanced
|
Hi Eduard van Valkenburg (@eavanvalkenburg) , please take a look when you get a chance |
|
Eduard van Valkenburg (@eavanvalkenburg) - the pipeline failure is fixed. Could you please retrigger the pipeline when you get a chance? Thanks! |
|
Eduard van Valkenburg (@eavanvalkenburg) - I moved the alias parsing into core as you suggested (790ac8e), and fixed the typing failure in the new aliased-model tests (3d1e5c8). Could you please retrigger the pipeline when you get a chance? If everything is green, would it be possible to get this into the next release? We are waiting on structured output for the GitHub Copilot agent. Thanks! |
|
Dineshsuriya D (@droideronline) Hard-coding |
|
Eduard van Valkenburg (@eavanvalkenburg) - fixed in 6cdf1e0. Core now validates with the model's own configuration first, so name-keyed output (validate_by_name or populate_by_name) is accepted as before. Only if that fails does it retry with aliases only (pydantic 2.11+) to support alias-keyed provider output, and it re-raises the original error if both fail. Added regression tests for name-keyed output and for the original error on invalid output. |
|
Dineshsuriya D (@droideronline) One correctness issue remains in the alias fallback: defaulted aliased fields can silently lose the provider’s value. With |
|
Eduard van Valkenburg (@eavanvalkenburg) - good catch, fixed in b2dc326. Core now validates with a single pass using by_alias=True and leaves by_name to the model's own configuration. Aliases are always accepted, so a defaulted aliased field keeps the provider's value instead of silently using its default, and models configured with validate_by_name or populate_by_name still accept name-keyed output. The retry logic is gone. Added defaulted-aliased-field regressions for the core response and for both streaming and non-streaming GitHubCopilotAgent runs. |
|
Dineshsuriya D (@droideronline) Please add a note to the PR description that this change depends on the next |
|
Eduard van Valkenburg (@eavanvalkenburg) - added a dependency note to the PR description: this change depends on the next agent-framework-core version bump, and no dependency change is needed here since the bump will raise the floor. |
Forward response_format as response_schema to the Copilot SDK send and send_and_wait calls and keep it out of create_session kwargs. Parse AgentResponse.value in core with alias validation enabled while preserving each model's field-name validation. For streaming, only the root agent's final idle ends the run, aborted and autopilot idle events are handled like the SDK waiter, and events are correlated to the request ID returned by send so an earlier request cannot supply the structured value.
955c090 to
eb24f70
Compare
|
Eduard van Valkenburg (@eavanvalkenburg) - addressed the three streaming comments (request correlation, aborted idle, autopilot idle) and rebased onto the latest main, so the branch is now a single commit. Please take another look and retrigger the pipeline when you get a chance. Thanks! |
|
Fixed the failing typing check ( |


Motivation & Context
GitHubCopilotAgentignoredresponse_format, so structured output was unavailable even though the Copilot SDK supports it (github/copilot-sdk#2590, in SDK v1.0.15 and later, within the existing>=1.0.16pin).Description & Review Guide
response_format(Pydantic model type or JSON Schema mapping) toGitHubCopilotOptions.response_schematosend_and_wait(non-streaming) andsend(streaming). Per-run options overridedefault_options.response_formatis stripped from thecreate_sessionkwargs so it no longer reaches the SDK session factory.AgentResponse.valueis parsed from the final text: viaresponse_format=on the non-streaming response andoutput_format_type=in the streaming finalizer.response_formatthe SDK receivesresponse_schema=None, which is the existing behavior.Dependency note: This change depends on the next
agent-framework-coreversion bump. It relies on the shared structured-output parsing fix in core (alias-aware validation ofAgentResponse.value), which core 1.22.0 does not contain, and the currentagent-framework-github-copilotdependency floor still permits 1.22.0. No dependency change is needed in this PR; the next version bump will raise the floor.Related Issue
Fixes #9809
AI Assistance
AI assistance details: implementation and tests.
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.