From 7276a38d9af3fa860979a39ec9bd9ce3da4c547a Mon Sep 17 00:00:00 2001 From: Rodrigo Ipince Date: Wed, 12 Nov 2025 19:30:47 -0500 Subject: [PATCH 1/2] [aisdk] Allow for empty reasoning blocks (observed behavior) --- aisdk/ai/provider/openai/internal/codec/decode.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/aisdk/ai/provider/openai/internal/codec/decode.go b/aisdk/ai/provider/openai/internal/codec/decode.go index d719e257..b87410db 100644 --- a/aisdk/ai/provider/openai/internal/codec/decode.go +++ b/aisdk/ai/provider/openai/internal/codec/decode.go @@ -110,9 +110,6 @@ func decodeReasoning(item responses.ResponseOutputItemUnion) (*api.ReasoningBloc } reasoningItem := item.AsReasoning() - if len(reasoningItem.Summary) == 0 { - return nil, fmt.Errorf("reasoning item has no summary") - } // For now, we'll concatenate all summary texts with newlines if there are multiple // Another option would be to return a slice of ReasoningBlocks. @@ -125,9 +122,9 @@ func decodeReasoning(item responses.ResponseOutputItemUnion) (*api.ReasoningBloc texts = append(texts, summary.Text) } - if len(texts) == 0 { - return nil, fmt.Errorf("no valid text found in reasoning summaries") - } + // NOTE: we don't check that the text is non-empty because sometimes the model returns an empty + // reasoning block. That behavior is technically against the API spec, but it's been observed in practice. + // Consider omitting the ReasoningBlock and adding a warning instead. return &api.ReasoningBlock{ Text: strings.Join(texts, "\n"), From fa867348ddde06d652ac0d83c1878673c85d0b2c Mon Sep 17 00:00:00 2001 From: Rodrigo Ipince Date: Wed, 12 Nov 2025 19:37:05 -0500 Subject: [PATCH 2/2] fix test --- aisdk/ai/provider/openai/internal/codec/decode_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aisdk/ai/provider/openai/internal/codec/decode_test.go b/aisdk/ai/provider/openai/internal/codec/decode_test.go index a94ebeb5..6ce77151 100644 --- a/aisdk/ai/provider/openai/internal/codec/decode_test.go +++ b/aisdk/ai/provider/openai/internal/codec/decode_test.go @@ -1192,7 +1192,7 @@ func TestDecodeReasoning(t *testing.T) { "id": "reason_123", "summary": [] }`, - wantErr: "reasoning item has no summary", + want: &api.ReasoningBlock{}, }, { name: "empty text in summary",