Skip to content

openai integration content string handling - #3949

Merged
akshaydeo merged 6 commits into
devfrom
06-01-openai_integration_content_string_handling
Jun 2, 2026
Merged

openai integration content string handling#3949
akshaydeo merged 6 commits into
devfrom
06-01-openai_integration_content_string_handling

Conversation

@akshaydeo

@akshaydeo akshaydeo commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Summary

When replaying reasoning items through the OpenAI Responses API (e.g. Codex/GPT-5.5), the content field on a reasoning message can arrive as a string (notably an empty "" after round-tripping). OpenAI types reasoning.content as an array of reasoning_text blocks and rejects a string value with "expected an array ... got a string". This fix normalizes string content on outbound reasoning messages: empty strings are dropped entirely, and non-empty strings are promoted to a reasoning_text block.

Changes

  • In ToOpenAIResponsesRequest, when a reasoning message has Content.ContentStr set, the string is either dropped (if empty) or converted to a ResponsesMessageContentBlock with type reasoning_text (if non-empty). The reassignment operates on the local value copy to avoid mutating the caller's input.
  • Tests cover both the empty-string drop case (including a marshal check to ensure "content":"" never appears in the serialized output) and the non-empty string promotion case.

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

go test ./core/providers/openai/... -run TestToOpenAIResponsesRequest_ReasoningStringContent -v

Expected: both subtests (empty string content is dropped and non-empty string content becomes a reasoning_text block) pass, and the marshalled output does not contain "content":"" on any reasoning item.

Screenshots/Recordings

N/A

Breaking changes

  • Yes
  • No

Related issues

N/A

Security considerations

No auth, secrets, or PII implications. The fix only affects how reasoning message content is serialized before being sent to the OpenAI API.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Fixed handling of reasoning message content when formatted as strings in OpenAI responses
    • Fixed JSON serialization of empty content fields to ensure API compliance
  • Chores

    • Updated Go module dependencies across core, framework, and plugin packages for performance and security improvements
  • Tests

    • Added test coverage for reasoning content normalization and empty content marshaling

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9dd4796f-b294-4372-ba55-70b17022d21c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR fixes OpenAI Responses API content handling and coordinates transitive dependency upgrades across all modules. The functional changes normalize reasoning content representation and fix empty content marshaling to comply with API contracts. The dependency updates bring compression, encoding, authentication, observability, and Google platform libraries to newer versions across 15 modules.

Changes

OpenAI Responses API Content Handling

Layer / File(s) Summary
Empty content marshaling contract
core/schemas/responses.go, core/schemas/responses_test.go
ResponsesMessageContent.MarshalJSON emits empty string ("") instead of null when both content fields are nil, aligning with OpenAI API requirements. Test verifies both the field marshaling and parent message serialization include "content":"" not null.
Reasoning content string normalization
core/providers/openai/responses.go, core/providers/openai/responses_test.go
ToOpenAIResponsesRequest converts reasoning messages with ContentStr into proper ContentBlocks: drops empty strings entirely, converts non-empty strings to a single reasoning_text content block. Test validates both empty-string removal and non-empty conversion with JSON validation.

Transitive Dependency Version Updates

Layer / File(s) Summary
Core module dependencies
core/go.mod
Bumped brotli (v1.2.0→v1.2.1), sonic/sonic-loader, klauspost/compress, fasthttp, and protobuf across direct and indirect blocks.
Framework module dependencies
framework/go.mod
Upgraded google.golang.org/api (v0.274.0→v0.282.0), cloud.google.com/go/auth, brotli, sonic/loader, xds/go, envoyproxy/go-control-plane/envoy, protoc-gen-validate, mapstructure/v2, jwt/v5, googleapis/gax-go, klauspost/compress, fasthttp, OpenTelemetry contrib detectors/instrumentation, genproto, grpc, and protobuf.
Compat, logging, and otel plugins
plugins/compat/go.mod, plugins/logging/go.mod, plugins/otel/go.mod
Coordinated version bumps across sonic/loader, cloud.google.com/go/auth, brotli, xds/go, envoyproxy components, mapstructure/v2, jwt/v5, googleapis cert-proxy and gax-go, klauspost/compress, fasthttp, OpenTelemetry contrib (detectors/gcp, otelgrpc, otelhttp), Google API/genproto/grpc/protobuf.
Governance plugin dependencies
plugins/governance/go.mod
Updated sonic, cel-go, fasthttp, brotli, antlr, xds/go, envoyproxy, mapstructure/v2, jwt/v5, googleapis cert-proxy/gax-go, klauspost/compress, OpenTelemetry contrib, and Google platform libraries; removed stoewer/go-strcase.
Remaining plugin and transport modules
plugins/jsonparser/go.mod, plugins/maxim/go.mod, plugins/mocker/go.mod, plugins/prompts/go.mod, plugins/semanticcache/go.mod, plugins/telemetry/go.mod, transports/go.mod
All modules updated with consistent version bumps for compression (brotli, klauspost/compress), encoding (bytedance/sonic), HTTP (fasthttp), authentication (jwt/v5), Google Cloud (auth, googleapis cert-proxy, gax-go, api, genproto, grpc, protobuf), observability (OpenTelemetry contrib detectors and instrumentations), and infrastructure (xds/go, envoyproxy, mapstructure/v2).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • maximhq/bifrost#3584: Both PRs handle reasoning content representation in OpenAI Responses structures; this PR normalizes ContentStr to ContentBlocks during conversion, while #3584 ensures reasoning message types are correctly attached.

Suggested reviewers

  • danpiths

Poem

🐰 Whiskers twitching with delight,
Empty strings now shine so bright,
Reasoning blocks in proper rows,
Dependencies bumped—watch it grow!
Content marshals true and clean,
Hopping through the API scene! 🚀

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'openai integration content string handling' directly describes the main change: fixing how string content is handled in OpenAI Responses API integration for reasoning messages.
Description check ✅ Passed The PR description is comprehensive and follows the template structure with all key sections completed: Summary, Changes, Type of change, Affected areas, How to test, Breaking changes, Related issues, Security considerations, and Checklist.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 06-01-openai_integration_content_string_handling

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

Safe to merge; the normalization logic is correct, operates on value copies, and is well-tested.

The reasoning-message normalization in responses.go is correctly scoped, uses value semantics to avoid mutating caller input, and is covered by dedicated tests including a marshal-output check. The MarshalJSON fallback change in schemas/responses.go is global but the affected state (both fields nil on a non-nil pointer) is unreachable through normal deserialization and suppressed by omitempty on the outbound path.

core/schemas/responses.go — the MarshalJSON fallback is a global behavior change worth a second look to confirm no other code paths construct &ResponsesMessageContent{} with neither field set for non-reasoning message types.

Important Files Changed

Filename Overview
core/providers/openai/responses.go Adds ContentStr normalization for reasoning messages: drops empty strings (sets Content=nil) and promotes non-empty strings to a reasoning_text ContentBlock. Operates on a value copy so the caller's input is not mutated.
core/schemas/responses.go Changes MarshalJSON fallback from null to "" when both ContentStr and ContentBlocks are nil — a schema-layer change that applies to all ResponsesMessageContent usages, not only reasoning messages.
core/providers/openai/responses_test.go Adds two sub-tests for reasoning string-content normalization: empty string dropped (with marshal check) and non-empty string promoted to a reasoning_text block.
core/schemas/responses_test.go Adds TestResponsesMessageContentEmptyMarshalsToEmptyString verifying that an empty ResponsesMessageContent{} serializes as "" and that "content":null never appears.

Reviews (7): Last reviewed commit: "openai integration content string handli..." | Re-trigger Greptile

Comment thread core/providers/openai/responses.go Outdated
@akshaydeo
akshaydeo force-pushed the 06-01-openai_integration_content_string_handling branch 3 times, most recently from 3a811a7 to 3497c10 Compare June 1, 2026 17:47
@akshaydeo
akshaydeo force-pushed the 06-01-logs_adds_support_for_rendering_file_attachments branch from c2485e4 to 7a77a2e Compare June 1, 2026 17:47
@akshaydeo akshaydeo mentioned this pull request Jun 1, 2026
17 tasks
@akshaydeo
akshaydeo force-pushed the 06-01-openai_integration_content_string_handling branch from 3497c10 to d365c69 Compare June 2, 2026 06:59
@akshaydeo
akshaydeo force-pushed the 06-01-logs_adds_support_for_rendering_file_attachments branch from 7a77a2e to 29216bc Compare June 2, 2026 06:59
@akshaydeo
akshaydeo force-pushed the 06-01-openai_integration_content_string_handling branch from d365c69 to f282051 Compare June 2, 2026 07:37
@akshaydeo
akshaydeo force-pushed the 06-01-logs_adds_support_for_rendering_file_attachments branch 2 times, most recently from 693dc82 to 96acc40 Compare June 2, 2026 07:47
@akshaydeo
akshaydeo force-pushed the 06-01-openai_integration_content_string_handling branch from f282051 to 1b092da Compare June 2, 2026 07:47

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Full review triggered.

@akshaydeo akshaydeo mentioned this pull request Jun 2, 2026
18 tasks

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
transports/go.mod (1)

134-134: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Resolve leftover merge-conflict marker in go.mod (build blocker).

Line 134 includes <<<<<<< HEAD in a dependency comment, which makes go.mod invalid and can break go mod tidy/build tooling. Remove the conflict artifact and keep a single clean dependency entry.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@transports/go.mod` at line 134, Remove the leftover merge-conflict marker and
duplicate text from the go.mod dependency entry: locate the line containing
"github.com/mattn/go-sqlite3 v1.14.32 // indirect; indirect<<<<<<< HEAD" and
edit it to a single valid dependency comment (e.g., "github.com/mattn/go-sqlite3
v1.14.32 // indirect") so go.mod is syntactically valid and builds pass.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@core/providers/openai/responses_test.go`:
- Around line 236-287: After calling ToOpenAIResponsesRequest(bifrostReq) add
assertions that the original source message was not mutated: check
bifrostReq.Input[0].Content.ContentStr is still the original pointer/value and
that bifrostReq.Input[0].Content.ContentBlocks is nil or empty; do this in both
the "empty string content is dropped" and "non-empty string content becomes a
reasoning_text block" subtests to ensure the function works on a local copy and
does not populate ContentBlocks on the input message.

In `@core/providers/openai/responses.go`:
- Around line 154-165: The code currently only normalizes an empty ContentStr
but can still leave a zero-value schemas.ResponsesMessageContent (e.g.,
&schemas.ResponsesMessageContent{}), which will serialize to an empty string and
cause OpenAI rejections; update the block that handles message.Content in
core/providers/openai/responses.go to detect and drop zero-value content objects
as well—check if message.Content.ContentBlocks is nil or empty (and any other
fields are zero) and set message.Content = nil in that case, otherwise construct
the ResponsesMessageContent with a single ResponsesMessageContentBlock as you're
already doing (use schemas.ResponsesMessageContent, ContentBlocks, and
ResponsesOutputMessageContentTypeReasoning to locate the change).

---

Outside diff comments:
In `@transports/go.mod`:
- Line 134: Remove the leftover merge-conflict marker and duplicate text from
the go.mod dependency entry: locate the line containing
"github.com/mattn/go-sqlite3 v1.14.32 // indirect; indirect<<<<<<< HEAD" and
edit it to a single valid dependency comment (e.g., "github.com/mattn/go-sqlite3
v1.14.32 // indirect") so go.mod is syntactically valid and builds pass.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 01ac69c2-5e88-4c18-8b61-ddec791f212e

📥 Commits

Reviewing files that changed from the base of the PR and between 96acc40 and 1b092da.

⛔ Files ignored due to path filters (13)
  • core/go.sum is excluded by !**/*.sum
  • framework/go.sum is excluded by !**/*.sum
  • plugins/compat/go.sum is excluded by !**/*.sum
  • plugins/governance/go.sum is excluded by !**/*.sum
  • plugins/jsonparser/go.sum is excluded by !**/*.sum
  • plugins/logging/go.sum is excluded by !**/*.sum
  • plugins/maxim/go.sum is excluded by !**/*.sum
  • plugins/mocker/go.sum is excluded by !**/*.sum
  • plugins/otel/go.sum is excluded by !**/*.sum
  • plugins/prompts/go.sum is excluded by !**/*.sum
  • plugins/semanticcache/go.sum is excluded by !**/*.sum
  • plugins/telemetry/go.sum is excluded by !**/*.sum
  • transports/go.sum is excluded by !**/*.sum
📒 Files selected for processing (17)
  • core/go.mod
  • core/providers/openai/responses.go
  • core/providers/openai/responses_test.go
  • core/schemas/responses.go
  • core/schemas/responses_test.go
  • framework/go.mod
  • plugins/compat/go.mod
  • plugins/governance/go.mod
  • plugins/jsonparser/go.mod
  • plugins/logging/go.mod
  • plugins/maxim/go.mod
  • plugins/mocker/go.mod
  • plugins/otel/go.mod
  • plugins/prompts/go.mod
  • plugins/semanticcache/go.mod
  • plugins/telemetry/go.mod
  • transports/go.mod

Comment thread core/providers/openai/responses_test.go
Comment thread core/providers/openai/responses.go Outdated
@akshaydeo
akshaydeo force-pushed the 06-01-logs_adds_support_for_rendering_file_attachments branch from 7a8fb4f to a3b4a05 Compare June 2, 2026 08:36
@akshaydeo
akshaydeo force-pushed the 06-01-openai_integration_content_string_handling branch from 1b092da to 58e1a89 Compare June 2, 2026 08:36

akshaydeo commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

Merge activity

  • Jun 2, 8:41 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 2, 8:45 AM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo
akshaydeo changed the base branch from 06-01-logs_adds_support_for_rendering_file_attachments to graphite-base/3949 June 2, 2026 08:44
@akshaydeo
akshaydeo changed the base branch from graphite-base/3949 to dev June 2, 2026 08:44
@akshaydeo
akshaydeo merged commit 9491e54 into dev Jun 2, 2026
9 of 10 checks passed
@akshaydeo
akshaydeo deleted the 06-01-openai_integration_content_string_handling branch June 2, 2026 08:45
akshaydeo added a commit that referenced this pull request Jun 2, 2026
## Summary

When replaying reasoning items through the OpenAI Responses API (e.g. Codex/GPT-5.5), the `content` field on a reasoning message can arrive as a string (notably an empty `""` after round-tripping). OpenAI types `reasoning.content` as an array of `reasoning_text` blocks and rejects a string value with `"expected an array ... got a string"`. This fix normalizes string content on outbound reasoning messages: empty strings are dropped entirely, and non-empty strings are promoted to a `reasoning_text` block.

## Changes

- In `ToOpenAIResponsesRequest`, when a reasoning message has `Content.ContentStr` set, the string is either dropped (if empty) or converted to a `ResponsesMessageContentBlock` with type `reasoning_text` (if non-empty). The reassignment operates on the local value copy to avoid mutating the caller's input.
- Tests cover both the empty-string drop case (including a marshal check to ensure `"content":""` never appears in the serialized output) and the non-empty string promotion case.

## Type of change

- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [ ] Core (Go)
- [ ] Transports (HTTP)
- [x] Providers/Integrations
- [ ] Plugins
- [ ] UI (React)
- [ ] Docs

## How to test

```sh
go test ./core/providers/openai/... -run TestToOpenAIResponsesRequest_ReasoningStringContent -v
```

Expected: both subtests (`empty string content is dropped` and `non-empty string content becomes a reasoning_text block`) pass, and the marshalled output does not contain `"content":""` on any reasoning item.

## Screenshots/Recordings

N/A

## Breaking changes

- [ ] Yes
- [x] No

## Related issues

N/A

## Security considerations

No auth, secrets, or PII implications. The fix only affects how reasoning message content is serialized before being sent to the OpenAI API.

## Checklist

- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

## Release Notes

* **Bug Fixes**
  * Fixed handling of reasoning message content when formatted as strings in OpenAI responses
  * Fixed JSON serialization of empty content fields to ensure API compliance

* **Chores**
  * Updated Go module dependencies across core, framework, and plugin packages for performance and security improvements

* **Tests**
  * Added test coverage for reasoning content normalization and empty content marshaling

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
akshaydeo added a commit that referenced this pull request Jun 4, 2026
## Summary

When replaying reasoning items through the OpenAI Responses API (e.g. Codex/GPT-5.5), the `content` field on a reasoning message can arrive as a string (notably an empty `""` after round-tripping). OpenAI types `reasoning.content` as an array of `reasoning_text` blocks and rejects a string value with `"expected an array ... got a string"`. This fix normalizes string content on outbound reasoning messages: empty strings are dropped entirely, and non-empty strings are promoted to a `reasoning_text` block.

## Changes

- In `ToOpenAIResponsesRequest`, when a reasoning message has `Content.ContentStr` set, the string is either dropped (if empty) or converted to a `ResponsesMessageContentBlock` with type `reasoning_text` (if non-empty). The reassignment operates on the local value copy to avoid mutating the caller's input.
- Tests cover both the empty-string drop case (including a marshal check to ensure `"content":""` never appears in the serialized output) and the non-empty string promotion case.

## Type of change

- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [ ] Core (Go)
- [ ] Transports (HTTP)
- [x] Providers/Integrations
- [ ] Plugins
- [ ] UI (React)
- [ ] Docs

## How to test

```sh
go test ./core/providers/openai/... -run TestToOpenAIResponsesRequest_ReasoningStringContent -v
```

Expected: both subtests (`empty string content is dropped` and `non-empty string content becomes a reasoning_text block`) pass, and the marshalled output does not contain `"content":""` on any reasoning item.

## Screenshots/Recordings

N/A

## Breaking changes

- [ ] Yes
- [x] No

## Related issues

N/A

## Security considerations

No auth, secrets, or PII implications. The fix only affects how reasoning message content is serialized before being sent to the OpenAI API.

## Checklist

- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

## Release Notes

* **Bug Fixes**
  * Fixed handling of reasoning message content when formatted as strings in OpenAI responses
  * Fixed JSON serialization of empty content fields to ensure API compliance

* **Chores**
  * Updated Go module dependencies across core, framework, and plugin packages for performance and security improvements

* **Tests**
  * Added test coverage for reasoning content normalization and empty content marshaling

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@coderabbitai coderabbitai Bot mentioned this pull request Jun 4, 2026
18 tasks
akshaydeo added a commit that referenced this pull request Jun 7, 2026
When replaying reasoning items through the OpenAI Responses API (e.g. Codex/GPT-5.5), the `content` field on a reasoning message can arrive as a string (notably an empty `""` after round-tripping). OpenAI types `reasoning.content` as an array of `reasoning_text` blocks and rejects a string value with `"expected an array ... got a string"`. This fix normalizes string content on outbound reasoning messages: empty strings are dropped entirely, and non-empty strings are promoted to a `reasoning_text` block.

- In `ToOpenAIResponsesRequest`, when a reasoning message has `Content.ContentStr` set, the string is either dropped (if empty) or converted to a `ResponsesMessageContentBlock` with type `reasoning_text` (if non-empty). The reassignment operates on the local value copy to avoid mutating the caller's input.
- Tests cover both the empty-string drop case (including a marshal check to ensure `"content":""` never appears in the serialized output) and the non-empty string promotion case.

- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

- [ ] Core (Go)
- [ ] Transports (HTTP)
- [x] Providers/Integrations
- [ ] Plugins
- [ ] UI (React)
- [ ] Docs

```sh
go test ./core/providers/openai/... -run TestToOpenAIResponsesRequest_ReasoningStringContent -v
```

Expected: both subtests (`empty string content is dropped` and `non-empty string content becomes a reasoning_text block`) pass, and the marshalled output does not contain `"content":""` on any reasoning item.

N/A

- [ ] Yes
- [x] No

N/A

No auth, secrets, or PII implications. The fix only affects how reasoning message content is serialized before being sent to the OpenAI API.

- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

* **Bug Fixes**
  * Fixed handling of reasoning message content when formatted as strings in OpenAI responses
  * Fixed JSON serialization of empty content fields to ensure API compliance

* **Chores**
  * Updated Go module dependencies across core, framework, and plugin packages for performance and security improvements

* **Tests**
  * Added test coverage for reasoning content normalization and empty content marshaling

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants