Skip to content

revert: nested BaseModel coercion (#295) - #375

Merged
jbeckwith-oai merged 2 commits into
mainfrom
codex/revert-nested-model-coercion
Aug 13, 2026
Merged

revert: nested BaseModel coercion (#295)#375
jbeckwith-oai merged 2 commits into
mainfrom
codex/revert-nested-model-coercion

Conversation

@jbeckwith-oai

Copy link
Copy Markdown
Contributor

Summary

  • Reverts fix: coerce nested BaseModel fields #295 as a standalone mechanical revert.
  • Adds focused characterization tests for the published raw-request / parsed-response BaseModel contract.
  • Does not introduce a replacement union or discriminator design.

Commit structure

  1. b269a43e is the literal Git revert of merge commit e5152a92962251ce76ceb3d89ec0b6b37fa4efdb.
  2. 6e8650e1 adds only the compatibility test suite.

Keeping those changes separate makes the rollback itself directly auditable and the additional contract coverage independently reviewable.

Why

#295 globally coerced nested request-model values, changing the documented contract that BaseModel#[] and #to_h expose the raw values callers supplied. The broader conversion changes also interact unsafely with optional discriminators and schemas where multiple variants share the same discriminator.

The previous forward-fix PR #373 was closed rather than repurposed. Draft #370 was also closed; issue #287 remains open for a narrower streaming-scoped solution after the model system is redesigned from first principles.

Compatibility coverage

  • raw request identity through accessors, #[], #to_h, and #deep_to_h
  • idiomatic nested fetch chains such as params.to_h.fetch(:input).fetch(0).fetch(:type)
  • request serialization after in-place mutation of caller-owned hashes
  • parsed-model symbol access, equality, and hashing
  • response coercion retaining expected nested model objects

Generator scope

No Castiron change is required. Castiron intentionally excludes the SDK-owned lib/openai/internal/ runtime, its signatures, and the handwritten test tree, so generated output is unchanged.

Validation

  • focused BaseModel suite: 17 runs, 261 assertions
  • focused compatibility suite: 9 runs, 39 assertions
  • full suite via the canonical scripts/test entry point on Ruby 3.3.12, 3.4.10, and 4.0.6: 613 runs, 2,256 assertions on each
  • bundle exec rake lint: RuboCop, Sorbet, and 1,212 RBS files green
  • bundle exec rake build:gem
  • thermonuclear code-quality review: no findings

@jbeckwith-oai
jbeckwith-oai marked this pull request as ready for review August 12, 2026 22:54
@jbeckwith-oai
jbeckwith-oai requested a review from a team as a code owner August 12, 2026 22:54
@openai-sdks

openai-sdks Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

OkTest Summary

237/237 SDK tests passed in 8.914s for Ruby SDK PR #375.

Test results — 42 files
Test Result Time
tests/chat-completions-complex-body.test.ts ✅ Passed 170ms
tests/chat-completions-create.test.ts ✅ Passed 256ms
tests/chat-completions-stream.test.ts ✅ Passed 141ms
tests/files-content-binary.test.ts ✅ Passed 235ms
tests/files-create-multipart.test.ts ✅ Passed 249ms
tests/files-list-pagination.test.ts ✅ Passed 193ms
tests/initialize-config.test.ts ✅ Passed 188ms
tests/instance-isolation.test.ts ✅ Passed 279ms
tests/models-list.test.ts ✅ Passed 203ms
tests/responses-background-lifecycle.test.ts ✅ Passed 242ms
tests/responses-body-method-errors.test.ts ✅ Passed 455ms
tests/responses-cancel-timeout.test.ts ✅ Passed 207ms
tests/responses-cancel.test.ts ✅ Passed 253ms
tests/responses-compact-retries.test.ts ✅ Passed 284ms
tests/responses-compact.test.ts ✅ Passed 212ms
tests/responses-create-advanced-stream.test.ts ✅ Passed 135ms
tests/responses-create-advanced.test.ts ✅ Passed 162ms
tests/responses-create-disconnect.test.ts ✅ Passed 157ms
tests/responses-create-errors.test.ts ✅ Passed 293ms
tests/responses-create-malformed-api-responses.test.ts ✅ Passed 132ms
tests/responses-create-retries.test.ts ✅ Passed 282ms
tests/responses-create-stream-failures.test.ts ✅ Passed 134ms
tests/responses-create-stream-timeout.test.ts ✅ Passed 236ms
tests/responses-create-stream-wire.test.ts ✅ Passed 2.064s
tests/responses-create-stream.test.ts ✅ Passed 106ms
tests/responses-create-terminal-states.test.ts ✅ Passed 264ms
tests/responses-create-timeout.test.ts ✅ Passed 213ms
tests/responses-create.test.ts ✅ Passed 348ms
tests/responses-delete.test.ts ✅ Passed 301ms
tests/responses-input-items-errors.test.ts ✅ Passed 189ms
tests/responses-input-items-list.test.ts ✅ Passed 181ms
tests/responses-input-items-options.test.ts ✅ Passed 190ms
tests/responses-input-tokens-count-timeout.test.ts ✅ Passed 285ms
tests/responses-input-tokens-count.test.ts ✅ Passed 269ms
tests/responses-malformed-inputs.test.ts ✅ Passed 2.23s
tests/responses-not-found-errors.test.ts ✅ Passed 352ms
tests/responses-parse.test.ts ✅ Passed 209ms
tests/responses-retrieve-retries.test.ts ✅ Passed 287ms
tests/responses-retrieve.test.ts ✅ Passed 243ms
tests/responses-stored-method-errors.test.ts ✅ Passed 741ms
tests/retry-behavior.test.ts ✅ Passed 1.988s
tests/sdk-error-shape.test.ts ✅ Passed 381ms

View OkTest run #31648868996

SDK merge (c4d144d8860b) · head (6e8650e1408d) · base (919977919667) · OkTest (a845fa206fa4)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6e8650e140

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/openai/internal/type/union.rb
Comment thread lib/openai/internal/type/base_model.rb
Comment thread lib/openai/internal/type/union.rb
Comment thread lib/openai/internal/type/base_model.rb
Comment thread lib/openai/internal/type/array_of.rb
Comment thread lib/openai/internal/type/array_of.rb

Copy link
Copy Markdown
Contributor Author

Automated review identified six pre-#295 converter behaviors that this literal rollback intentionally restores. They are now tracked together in #376 with explicit regression-coverage requirements: union error isolation, nullable fields, strictness preservation, existing-model identity, collection error retention, and nullable collection matchers.

I replied to and resolved each inline thread as separately tracked follow-up work. No code was added to this PR because doing so would make #375 a partial model-conversion redesign rather than the standalone rollback requested here.

@jbeckwith-oai jbeckwith-oai added the generator Touches generated SDK files label Aug 12, 2026
@jbeckwith-oai
jbeckwith-oai added this pull request to the merge queue Aug 13, 2026
Merged via the queue into main with commit 65fa76e Aug 13, 2026
13 checks passed
@jbeckwith-oai
jbeckwith-oai deleted the codex/revert-nested-model-coercion branch August 13, 2026 15:53
@openai-sdks openai-sdks Bot mentioned this pull request Aug 12, 2026
virelai2604 pushed a commit to virelai2604/openai-ruby that referenced this pull request Aug 15, 2026
Automated Release PR
---


##
[0.79.0](openai/openai-ruby@v0.78.0...v0.79.0)
(2026-08-14)


### Features

* add HTTP response observability
([openai#365](openai#365))
([48d36b7](openai@48d36b7))
* add Tapioca typing for structured outputs
([openai#364](openai#364))
([738e2b4](openai@738e2b4))
* **api:** Add new model identifiers and remove audit log source
([e0a4bc5](openai@e0a4bc5))
* **api:** add WebSocket stream IDs
([openai#387](openai#387))
([5880287](openai@5880287))
* **api:** add workload identity access token issued event
([openai#372](openai#372))
([9199779](openai@9199779))
* **api:** deprecate Sora video APIs
([openai#386](openai#386))
([0664456](openai@0664456))
* **client:** add default headers
([openai#369](openai#369))
([d516874](openai@d516874))
* expose request IDs
([openai#352](openai#352))
([c15fb7b](openai@c15fb7b))
* support Azure OpenAI v1
([openai#355](openai#355))
([c1d223e](openai@c1d223e))


### Bug Fixes

* **api:** Add new model identifiers and remove audit log source
([openai#360](openai#360))
([e0a4bc5](openai@e0a4bc5))
* **api:** allow nil timeout in client signatures
([openai#363](openai#363))
([e52ca61](openai@e52ca61))
* **api:** document file upload metadata defaults
([openai#361](openai#361))
([b4bc1ea](openai@b4bc1ea))
* coerce nested BaseModel fields
([openai#295](openai#295))
([e5152a9](openai@e5152a9))
* enable streaming when retrieving responses
([openai#413](openai#413))
([fd85182](openai@fd85182))
* encode multipart array and nested fields
([openai#348](openai#348))
([1c71a1e](openai@1c71a1e))
* honor workload identity environment defaults
([openai#398](openai#398))
([f4afea1](openai@f4afea1))
* keep required path parameters out of resource query strings
([openai#402](openai#402))
([6768a7c](openai@6768a7c))
* loading after ActiveSupport 6 subclass extensions
([openai#346](openai#346))
([20fbb09](openai@20fbb09))
* make SDK debug body logging fail closed
([openai#411](openai#411))
([c4f7284](openai@c4f7284))
* package every README-linked guide and example
([openai#382](openai#382))
([ddecd0f](openai@ddecd0f))
* preserve binary multipart stream reads
([openai#354](openai#354))
([b3a1ba7](openai@b3a1ba7))
* preserve existing BaseModel instances during coercion
([openai#400](openai#400))
([fbd8560](openai@fbd8560))
* preserve prefixed idempotency headers on redirects
([openai#404](openai#404))
([c380e13](openai@c380e13))
* preserve stream identity with HTTP logging
([openai#384](openai#384))
([640a1fe](openai@640a1fe))
* prevent symbol-keyed headers from bypassing security filters
([openai#383](openai#383))
([b8165af](openai@b8165af))
* redact sensitive query and form logging
([openai#389](openai#389))
([7aa54e4](openai@7aa54e4))
* reject invalid webhook signing secrets
([openai#403](openai#403))
([ad12458](openai@ad12458))
* remove unsound structured-output Tapioca compiler
([openai#405](openai#405))
([826769a](openai@826769a))
* restore RuboCop coverage for RBI files
([openai#388](openai#388))
([d2d4b5d](openai@d2d4b5d))
* return values from interruptible enumerator
([openai#350](openai#350))
([327dad7](openai@327dad7))
* strip credential headers on cross-origin redirects
([openai#391](openai#391))
([f50f08c](openai@f50f08c))
* tighten JSON, JSONL, and SSE content type matching
([openai#277](openai#277))
([66359a0](openai@66359a0))
* use API field names in structured output schemas
([openai#390](openai#390))
([d1e3cf3](openai@d1e3cf3))
* validate and bound retry delays
([openai#392](openai#392))
([fff94e7](openai@fff94e7))
* **webhooks:** support Rack and case-insensitive HTTP headers
([openai#401](openai#401))
([37de980](openai@37de980))


### Reverts

* nested BaseModel coercion
([openai#295](openai#295))
([openai#375](openai#375))
([65fa76e](openai@65fa76e))


### Chores

* Cover Ruby files at the SDK root
([openai#362](openai#362))
([d11f25b](openai@d11f25b))
* enforce boolean symbol lint
([openai#395](openai#395))
([fafdf2e](openai@fafdf2e))
* enforce deprecated constant lint
([openai#379](openai#379))
([0def912](openai@0def912))
* enforce duplicate match pattern lint
([openai#380](openai#380))
([7a8f2fb](openai@7a8f2fb))
* enforce empty else lint
([openai#396](openai#396))
([1e073c1](openai@1e073c1))
* enforce line length lint
([openai#406](openai#406))
([4592061](openai@4592061))
* enforce line length on base models
([openai#416](openai#416))
([aef1e33](openai@aef1e33))
* enforce line length on requires
([openai#415](openai#415))
([c24e045](openai@c24e045))
* enforce missing RuboCop enable directives
([openai#368](openai#368))
([50046bf](openai@50046bf))
* enforce missing super lint
([openai#393](openai#393))
([2a42bd0](openai@2a42bd0))
* enforce nonempty pattern branches
([openai#409](openai#409))
([9d22d5c](openai@9d22d5c))
* enforce redundant directive lint
([openai#366](openai#366))
([8448a4c](openai@8448a4c))
* enforce redundant exception lint
([openai#397](openai#397))
([cbda8bc](openai@cbda8bc))
* enforce symbol conversion lint
([openai#381](openai#381))
([0531498](openai@0531498))
* enforce useless assignment lint
([openai#394](openai#394))
([9688836](openai@9688836))
* guard RuboCop suppression directives
([openai#408](openai#408))
([5b6e0dc](openai@5b6e0dc))
* lint Ruby files repository-wide
([openai#377](openai#377))
([8ca8426](openai@8ca8426))
* remove Stainless attribution and infrastructure
([openai#371](openai#371))
([33d2c86](openai@33d2c86))
* require MFA for gem releases
([openai#378](openai#378))
([71798ec](openai@71798ec))


### Documentation

* **api:** describe response stream event unions
([openai#412](openai#412))
([87d18ef](openai@87d18ef))
* clarify file upload metadata
([openai#358](openai#358))
([698ac65](openai@698ac65)),
closes [openai#243](openai#243)
* document fiber scheduler concurrency
([openai#357](openai#357))
([25a7bbc](openai@25a7bbc))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: openai-sdks[bot] <284451331+openai-sdks[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

generator Touches generated SDK files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants