Skip to content

Python: Fix OpenAIChatCompletionClient passing raw JSON-Schema dict response_format through unwrapped - #7199

Merged
Giles Odigwe (giles17) merged 4 commits into
microsoft:mainfrom
exp-ouroborous:fix/chat-completions-response-format-wrap
Jul 29, 2026
Merged

Python: Fix OpenAIChatCompletionClient passing raw JSON-Schema dict response_format through unwrapped#7199
Giles Odigwe (giles17) merged 4 commits into
microsoft:mainfrom
exp-ouroborous:fix/chat-completions-response-format-wrap

Conversation

@exp-ouroborous

Copy link
Copy Markdown
Contributor

Motivation and Context

Raw JSON-Schema dicts (e.g. {"type": "object", "properties": {...}}) passed as response_format are forwarded to the Chat Completions API verbatim, and OpenAI rejects them with a 400 (Invalid value: 'object'). The Responses-based OpenAIChatClient already auto-wraps the identical input (see _convert_response_format), so the two clients disagree on the same input. This bites the declarative path in particular, where the loader passes outputSchema.to_json_schema() output as a bare dict.

Description

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible (test_openai_chat_completion_client.py: 77 passed, 20 skipped)
  • Is this a breaking change? No — previously-rejected inputs now work; valid inputs are unchanged.

Copilot AI review requested due to automatic review settings July 19, 2026 15:27
@giles17 Giles Odigwe (giles17) added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python .NET Usage: [Issues, PRs], Target: .Net labels Jul 19, 2026
@github-actions github-actions Bot changed the title Python: Fix OpenAIChatCompletionClient passing raw JSON-Schema dict response_format through unwrapped .NET: Python: Fix OpenAIChatCompletionClient passing raw JSON-Schema dict response_format through unwrapped Jul 19, 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.

Pull request overview

This PR fixes Python OpenAIChatCompletionClient handling of response_format when callers pass a raw JSON-Schema dict by normalizing/wrapping it into the Chat Completions json_schema envelope (bringing it in line with the Responses-based client), and adds unit tests for the new behavior. It also introduces a new .NET “AgentLearn” learning project plus several large research/ markdown documents and repo-level developer settings.

Changes:

  • Python: normalize raw JSON-Schema dict response_format values in OpenAIChatCompletionClient and add tests for wrapping/title→name behavior.
  • .NET: add dotnet/learn/AgentLearn sample app (workflows + HITL + tests) and a dotnet/samples/run.bash helper script.
  • Docs/config: add research/ documentation, new dotnet/learn docs/config, and repo-level VS Code/default-solution and gitignore updates.

Reviewed changes

Copilot reviewed 40 out of 41 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
research/README.md Adds a README describing the new research/ folder structure.
research/python/agentic-capabilities.md Adds Python agentic-capabilities research document.
research/dotnet/agentic-capabilities.md Adds .NET agentic-capabilities research document.
research/agentic-capabilities-overview.md Adds cross-language agentic-capabilities overview research document.
python/packages/openai/tests/openai/test_openai_chat_completion_client.py Adds tests for raw-schema wrapping and passthrough behaviors.
python/packages/openai/agent_framework_openai/_chat_completion_client.py Normalizes dict response_format by wrapping raw JSON Schema into json_schema.
dotnet/samples/run.bash Adds a helper script to run a .NET project with .env loaded.
dotnet/learn/README.md Adds README for the new dotnet/learn area.
dotnet/learn/Directory.Packages.props Disables central package management within dotnet/learn.
dotnet/learn/Directory.Build.targets Adds empty targets file to isolate from parent build targets.
dotnet/learn/Directory.Build.props Adds empty props file to isolate from parent build props.
dotnet/learn/CLAUDE.md Adds contributor guidance for the dotnet/learn area.
dotnet/learn/AgentLearn/tests/integration/StoryGeneratorWorkflowTests.cs Adds integration tests for StoryGenerator HITL workflow.
dotnet/learn/AgentLearn/tests/integration/MockChatClientHelper.cs Adds a helper to mock IChatClient responses for tests.
dotnet/learn/AgentLearn/tests/integration/JokeWriterWorkflowTests.cs Adds integration tests for JokeWriter workflows (single/sequential/concurrent).
dotnet/learn/AgentLearn/tests/integration/AgentLearn.IntegrationTests.csproj Adds integration test project definition.
dotnet/learn/AgentLearn/TaskKinds/StoryGenerator/StoryGenerator.http Adds REST client requests for StoryGenerator.
dotnet/learn/AgentLearn/TaskKinds/StoryGenerator/StoryGenerator.cs Adds StoryGenerator task kind (agents/workflow/handler/DI).
dotnet/learn/AgentLearn/TaskKinds/JokeWriter/JokeWriter.http Adds REST client requests for JokeWriter.
dotnet/learn/AgentLearn/TaskKinds/JokeWriter/JokeWriter.cs Adds JokeWriter task kind (models/executors/agents/workflows/handler/DI).
dotnet/learn/AgentLearn/Services/ITaskHandler.cs Adds task-handler abstraction for routing TaskKinds.
dotnet/learn/AgentLearn/Services/ChatClientFactory.cs Adds provider-based IChatClient factory + mock chat client.
dotnet/learn/AgentLearn/run.sh Adds script to start Jaeger and run AgentLearn.
dotnet/learn/AgentLearn/Properties/launchSettings.json Adds local launch settings for HTTP/HTTPS profiles.
dotnet/learn/AgentLearn/Program.cs Adds DI setup, OTel tracing, DevUI, and OpenAI-compatible endpoints.
dotnet/learn/AgentLearn/Models/TaskResponse.cs Adds DTO for /task responses.
dotnet/learn/AgentLearn/Models/TaskRequest.cs Adds DTO for /task requests.
dotnet/learn/AgentLearn/Models/TaskKind.cs Adds TaskKind enum for handler selection.
dotnet/learn/AgentLearn/Models/LlmOptions.cs Adds LLM provider config options DTO.
dotnet/learn/AgentLearn/Models/AgentMode.cs Adds workflow mode enum (Single/Sequential/Concurrent).
dotnet/learn/AgentLearn/Extensions/AIAgentBuilderExtensions.cs Adds tool-invocation logging middleware for agents.
dotnet/learn/AgentLearn/Controllers/TaskController.cs Adds /task endpoint controller.
dotnet/learn/AgentLearn/CLAUDE.md Adds project-specific conventions for AgentLearn.
dotnet/learn/AgentLearn/appsettings.json Adds baseline configuration including LLM defaults.
dotnet/learn/AgentLearn/appsettings.Development.json Adds dev configuration (debug logging).
dotnet/learn/AgentLearn/AgentLearn.csproj Adds AgentLearn web project definition and package references.
dotnet/learn/AgentLearn.sln Adds a Visual Studio solution for AgentLearn.
dotnet/learn/.gitignore Adds ignores for .env* files under dotnet/learn.
CLAUDE.md Adds repo-level Claude guidance file.
.vscode/settings.json Sets a repo-wide default .NET solution.
.gitignore Ignores .workspaces/ personal VS Code workspace files.

Comment thread dotnet/learn/AgentLearn/AgentLearn.csproj Outdated
Comment thread research/README.md Outdated
Comment thread dotnet/learn/CLAUDE.md Outdated
Comment thread .vscode/settings.json Outdated
Comment thread dotnet/learn/AgentLearn/Services/ChatClientFactory.cs Outdated
…esponse_format through unwrapped

Raw schema dicts (e.g. {"type": "object", ...}) were forwarded to the
Chat Completions API verbatim, which OpenAI rejects with a 400. The
Responses client already auto-wraps the same input. Mirror its raw-schema
detection (primitive types / schema keywords), wrap into the
{"type": "json_schema", "json_schema": {...}} envelope with
additionalProperties: false injection and title -> name promotion, and
leave already-valid response_format dicts untouched.

Fixes microsoft#7197

(cherry picked from commit dce5c3b)
@exp-ouroborous
Binit Mohanty (exp-ouroborous) force-pushed the fix/chat-completions-response-format-wrap branch from dce5c3b to 2351bd5 Compare July 19, 2026 15:32
@exp-ouroborous

Copy link
Copy Markdown
Contributor Author

Note for reviewers: the earlier review threads (research/, dotnet/learn/, .vscode/settings.json, AgentLearn.csproj) referenced unrelated files accidentally included from a stale fork base — the branch has been rebuilt as a single commit on top of main and those files are no longer part of this PR (now 2 files: _chat_completion_client.py + its tests).

@exp-ouroborous
Binit Mohanty (exp-ouroborous) marked this pull request as ready for review July 19, 2026 15:52
@exp-ouroborous

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

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

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

@exp-ouroborous Binit Mohanty (exp-ouroborous) changed the title .NET: Python: Fix OpenAIChatCompletionClient passing raw JSON-Schema dict response_format through unwrapped Python: Fix OpenAIChatCompletionClient passing raw JSON-Schema dict response_format through unwrapped Jul 19, 2026
@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/openai/agent_framework_openai
   _chat_completion_client.py4021995%468, 564–565, 569, 764, 846, 848, 853, 856, 957, 959, 976, 997, 1005, 1029, 1042, 1075, 1098, 1419
TOTAL45609448090% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
9418 34 💤 0 ❌ 0 🔥 2m 5s ⏱️

…rmat dicts

Adds a response_format_raw_json_schema param to test_integration_options in
both the Chat Completions and Responses client test suites, proving the same
bare schema dict (title set, additionalProperties omitted) round-trips through
both live APIs and yields parsed structured output.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@eavanvalkenburg

Copy link
Copy Markdown
Member

Binit Mohanty (@exp-ouroborous) please check the failing action

auto-merge was automatically disabled July 29, 2026 10:23

Head branch was pushed to by a user without write access

@giles17
Giles Odigwe (giles17) added this pull request to the merge queue Jul 29, 2026
Merged via the queue into microsoft:main with commit ce2208c Jul 29, 2026
37 checks passed
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 .NET Usage: [Issues, PRs], Target: .Net python Usage: [Issues, PRs], Target: Python

Projects

None yet

6 participants