Skip to content

fix: preserve binary multipart stream reads - #354

Merged
jbeckwith-oai merged 2 commits into
mainfrom
codex/canonical-read-io-adapter-fix
Aug 10, 2026
Merged

fix: preserve binary multipart stream reads#354
jbeckwith-oai merged 2 commits into
mainfrom
codex/canonical-read-io-adapter-fix

Conversation

@jbeckwith-oai

Copy link
Copy Markdown
Contributor

Summary

  • preserve arbitrary binary bytes when multipart request bodies yield a mix of UTF-8 and binary chunks
  • honor IO#read(max_len, out_string) byte limits, buffering, EOF, negative-length, and output-buffer semantics for Enumerator-backed bodies
  • retain native IO and StringIO delegation, including implicit to_int length conversion
  • update RBI/RBS contracts and add focused regression coverage

This fixes #317 and consolidates the complete behavior needed from #275, #294, and #324 on the current SDK-owned ReadIOAdapter implementation.

Ownership

This is handwritten SDK runtime behavior introduced as an SDK-owned component in #345. It does not change OpenAPI inputs, Castiron facts, renderer rules, templates, or generator configuration.

Validation

  • mise exec ruby@4.0.6 -- ./scripts/test — 531 runs, 1,736 assertions, 0 failures
  • mise exec ruby@4.0.6 -- bundle exec rake lint — RuboCop, Sorbet, and 1,211 RBS files clean
  • mise exec ruby@4.0.6 -- bundle exec rake build:gem
  • installed-gem adapter probe
  • Ruby 3.3.12 mixed-encoding compatibility probe
  • 1,000 randomized read sequences compared against StringIO
  • real local HTTP multipart upload with a 1 MiB binary file and UTF-8 prompt, verified byte-for-byte by SHA-256

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

openai-sdks Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

OkTest Summary

237/237 SDK tests passed in 8.777s for Ruby SDK PR #354.

Test results — 42 files
Test Result Time
tests/chat-completions-complex-body.test.ts ✅ Passed 175ms
tests/chat-completions-create.test.ts ✅ Passed 246ms
tests/chat-completions-stream.test.ts ✅ Passed 125ms
tests/files-content-binary.test.ts ✅ Passed 297ms
tests/files-create-multipart.test.ts ✅ Passed 261ms
tests/files-list-pagination.test.ts ✅ Passed 201ms
tests/initialize-config.test.ts ✅ Passed 199ms
tests/instance-isolation.test.ts ✅ Passed 260ms
tests/models-list.test.ts ✅ Passed 171ms
tests/responses-background-lifecycle.test.ts ✅ Passed 192ms
tests/responses-body-method-errors.test.ts ✅ Passed 400ms
tests/responses-cancel-timeout.test.ts ✅ Passed 294ms
tests/responses-cancel.test.ts ✅ Passed 203ms
tests/responses-compact-retries.test.ts ✅ Passed 243ms
tests/responses-compact.test.ts ✅ Passed 210ms
tests/responses-create-advanced-stream.test.ts ✅ Passed 129ms
tests/responses-create-advanced.test.ts ✅ Passed 243ms
tests/responses-create-disconnect.test.ts ✅ Passed 161ms
tests/responses-create-errors.test.ts ✅ Passed 259ms
tests/responses-create-malformed-api-responses.test.ts ✅ Passed 134ms
tests/responses-create-retries.test.ts ✅ Passed 268ms
tests/responses-create-stream-failures.test.ts ✅ Passed 134ms
tests/responses-create-stream-timeout.test.ts ✅ Passed 215ms
tests/responses-create-stream-wire.test.ts ✅ Passed 2.004s
tests/responses-create-stream.test.ts ✅ Passed 132ms
tests/responses-create-terminal-states.test.ts ✅ Passed 250ms
tests/responses-create-timeout.test.ts ✅ Passed 298ms
tests/responses-create.test.ts ✅ Passed 351ms
tests/responses-delete.test.ts ✅ Passed 232ms
tests/responses-input-items-errors.test.ts ✅ Passed 194ms
tests/responses-input-items-list.test.ts ✅ Passed 186ms
tests/responses-input-items-options.test.ts ✅ Passed 217ms
tests/responses-input-tokens-count-timeout.test.ts ✅ Passed 288ms
tests/responses-input-tokens-count.test.ts ✅ Passed 251ms
tests/responses-malformed-inputs.test.ts ✅ Passed 2.173s
tests/responses-not-found-errors.test.ts ✅ Passed 287ms
tests/responses-parse.test.ts ✅ Passed 210ms
tests/responses-retrieve-retries.test.ts ✅ Passed 280ms
tests/responses-retrieve.test.ts ✅ Passed 227ms
tests/responses-stored-method-errors.test.ts ✅ Passed 676ms
tests/retry-behavior.test.ts ✅ Passed 1.993s
tests/sdk-error-shape.test.ts ✅ Passed 351ms

View OkTest run #31431008263

SDK merge (e9a10f6ed8a3) · head (f711f4784e9b) · base (1c71a1eccdee) · OkTest (91635c6a2723)

Comment thread test/openai/internal/util_test.rb
@jbeckwith-oai jbeckwith-oai added the generator Touches generated SDK files label Aug 10, 2026
@jbeckwith-oai
jbeckwith-oai added this pull request to the merge queue Aug 10, 2026
Merged via the queue into main with commit b3a1ba7 Aug 10, 2026
14 checks passed
@jbeckwith-oai
jbeckwith-oai deleted the codex/canonical-read-io-adapter-fix branch August 10, 2026 21:02
@openai-sdks openai-sdks Bot mentioned this pull request Aug 10, 2026
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.

Encoding::CompatibilityError during multipart file upload is swallowed and reported as a generic APIConnectionError ("Connection error.")

2 participants