Sitelet https://github.com/dotnet/extensions/issues/7760
Skip to content

Request to upgrade OpenAI library to 2.14.0 to fix bugs in OpenAI 2.13.0 #7760

Description

@zxyao145

Description

Summary

Two chained defects make the Responses API unusable against third-party OpenAI-compatible endpoints that emit "status": null on reasoning items:

  1. 2.13.0: DeserializeReasoningResponseItem lacks a null guard for the optional status property, so "status": null throws ArgumentOutOfRangeException and aborts the entire SSE stream.
  2. 2.14.0: the null guard was added, but the release also removed the public (experimental) struct OpenAI.Responses.GlobalMcpToolCallApprovalPolicy, which Microsoft.Extensions.AI.OpenAI 10.10.0 references from OpenAIResponsesChatClient.ToResponseTool. Any tool-carrying Responses call through the M.E.AI adapter now dies with TypeLoadException at JIT time.

Environment

  • OpenAI SDK: 2.13.0 (also tested 2.14.0)
  • Microsoft.Agents.AI.OpenAI 1.21.0 / Microsoft.Extensions.AI.OpenAI 10.10.0
  • .NET 10

Defect 1 — 2.13.0: no null guard on status (repro)

Third-party Responses-compatible backends may serialize the optional status field of a reasoning item as JSON null instead of omitting it (same class of report as openai/openai-dotnet#1342). Since status is optional per spec, null should deserialize the same as "absent".

This issue has already been addressed openai/openai-dotnet#1346 repaired.

Minimal repro — no network or API key required, uses the exact entry point the SSE pipeline uses (AsyncSseUpdateCollection → ModelReaderWriter):

using System.ClientModel.Primitives;
using OpenAI.Responses;

var json = """
           {"type":"response.output_item.added","output_index":0,
            "item":{"type":"reasoning","id":"rs_1","status":null,"summary":[]}}
           """;

#pragma warning disable OPENAI001
var update = ModelReaderWriter.Read<StreamingResponseUpdate>(BinaryData.FromString(json));
#pragma warning restore OPENAI001

Actual (2.13.0):

System.ArgumentOutOfRangeException: Unknown ReasoningStatus value. (Parameter 'value')
   at OpenAI.Responses.ReasoningStatusExtensions.ToReasoningStatus(String value)
   at OpenAI.Responses.ReasoningResponseItem.DeserializeReasoningResponseItem(...)

Expected: status: null treated as absent (ReasoningStatus? status = null).

Actual (2.14.0): passes — decompilation confirms the guard was added:

// 2.13.0 (generated) — no null check; GetString() on JSON null returns C# null
else if (item.NameEquals("status"))
{
    status = item.Value.GetString().ToReasoningStatus();  // throws
}

// 2.14.0 (generated)
else if (item.NameEquals("status"))
{
    if (item.Value.ValueKind != JsonValueKind.Null)
    {
        status = item.Value.GetString().ToReasoningStatus();
    }
}

Defect 2 — 2.14.0: breaking removal of GlobalMcpToolCallApprovalPolicy

I tried importing OpenAI 2.14.0 package directly, but it caused this problem:

System.TypeLoadException: Could not load type 'OpenAI.Responses.GlobalMcpToolCallApprovalPolicy'
from assembly 'OpenAI, Version=2.14.0.0, Culture=neutral, PublicKeyToken=b4187f3e65366280'.
   at Microsoft.Extensions.AI.OpenAIResponsesChatClient.ToResponseTool(AITool tool, ChatOptions options, ToolSearchLookup toolSearchLookup)
   at Microsoft.Extensions.AI.OpenAIResponsesChatClient.AsCreateResponseOptions(...)
   at Microsoft.Extensions.AI.OpenAIResponsesChatClient.GetStreamingResponseAsync(...)

In 2.14.0, GlobalMcpToolCallApprovalPolicy has been renamed to DefaultMcpToolCallApprovalPolicy. The following is a screenshot of openai-dotnet CHANGELOG.

Image

Reproduction Steps

using System.ClientModel.Primitives;
using OpenAI.Responses;

var json = """
           {"type":"response.output_item.added","output_index":0,
            "item":{"type":"reasoning","id":"rs_1","status":null,"summary":[]}}
           """;

#pragma warning disable OPENAI001
var update = ModelReaderWriter.Read<StreamingResponseUpdate>(BinaryData.FromString(json));
#pragma warning restore OPENAI001

Expected behavior

Correct deserialization to obtain StreamResponseUpdate: status: null treated as absent (ReasoningStatus? status = null).

Actual behavior

2.13.0:

System.ArgumentOutOfRangeException: Unknown ReasoningStatus value. (Parameter 'value')
   at OpenAI.Responses.ReasoningStatusExtensions.ToReasoningStatus(String value)
   at OpenAI.Responses.ReasoningResponseItem.DeserializeReasoningResponseItem(...)

Unhandled exception. System.ArgumentOutOfRangeException: Unknown ReasoningStatus value. (Parameter 'value')
   at OpenAI.Responses.ReasoningStatusExtensions.ToReasoningStatus(String value)
   at OpenAI.Responses.ReasoningResponseItem.DeserializeReasoningResponseItem...

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-aiMicrosoft.Extensions.AI librariesbugThis issue describes a behavior which is not expected - a bug.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions