Skip to content

fix: parse SSE retry metadata as decimal - #624

Merged
jbeckwith-oai merged 1 commit into
mainfrom
codex/parse-sse-retry-decimal
Sep 4, 2026
Merged

fix: parse SSE retry metadata as decimal#624
jbeckwith-oai merged 1 commit into
mainfrom
codex/parse-sse-retry-decimal

Conversation

@jbeckwith-oai

@jbeckwith-oai jbeckwith-oai commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Problem

WHATWG SSE retry fields containing ASCII digits are decimal integers, but Ruby Integer(value) infers prefixes. On a valid Chat event stream, retry: 08 and retry: 09 raised ArgumentError before the following data event, while retry: 010 was interpreted as 8 instead of 10.

User-visible behavior

A public Chat stream_raw call now accepts legal leading-zero retry metadata and still yields the following chunk:

stream = client.chat.completions.stream_raw(
  model: "gpt-4o-mini",
  messages: [{role: :user, content: "Hello"}]
)
stream.each { |chunk| puts chunk.choices.first.delta.content }

With the same valid synthetic data event after it, retry: 08 previously raised ArgumentError; now the chunk is delivered and the retry metadata is 8. Likewise, retry: 010 is stored as 10, not 8. Required digit-only values 0, 8, 08, 09, and 010 map to 0, 8, 8, 9, and 10.

Fix

At the existing digit-only retry conversion in decode_sse, pass explicit base 10 to Integer. The existing ASCII-digit guard is unchanged, so malformed, signed, fractional, and non-ASCII retry values remain ignored.

Scope and compatibility

The diff is limited to that one numeric conversion and a focused regression test. It does not add reconnection, retry policy, parser state, payload limits, API changes, dependencies, generated changes, or alter event data, event IDs, UTF-8/BOM handling, fragments, line endings, EOF dispatch, or stream closing behavior.

Verification

  • Red proof: the new focused test raised ArgumentError for 08 in both public stream and metadata paths before the fix.
  • Focused regression: 2 runs, 10 assertions, 0 failures.
  • Existing util SSE tests: 63 runs, 287 assertions, 0 failures.
  • UTF-8 boundary tests: 5 runs, 8 assertions, 0 failures.
  • Chat completion streaming tests: 22 runs, 107 assertions, 0 failures.
  • Ruby formatting, RuboCop (2,880 files), and typecheck passed.
  • Serialized full suite against the current-spec mock: 1,658 runs, 14,680 assertions, 0 failures, 0 errors, 1 skip.
  • Trusted current-main public custom-code budget: 3,363 / 4,000 lines, 637 headroom.
  • Two consecutive fresh adversarial-review rounds with two independent read-only reviewers each were clean.
  • Bounded streaming/deserialization security review was clean; no new trust boundary, logging, allocation limit, state, or sink was introduced.

Limitations

The full suite retains one existing skipped test and emitted existing dependency/runtime warnings. No live API examples were run.

@jbeckwith-oai
jbeckwith-oai requested a review from a team as a code owner September 4, 2026 22:56
@jbeckwith-oai jbeckwith-oai added codex-maintenance Low-risk maintenance changes created by Codex autoimprove Automated repository-health improvements labels Sep 4, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-04T22:57:05.303287Z 08fcfd1 PR opened
🔒 Security Review Completed 2026-09-04T22:58:22.633181Z 08fcfd1 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Castiron custom code

✅ No new custom-code files detected.

47 mixed files remain; 0 existing customizations changed.

Compared 6b9ee8729c3a08fcfd1a7f6c. Generated baselines verified.

47 existing customizations unchanged
  • lib/openai.rb
  • lib/openai/client.rb
  • lib/openai/models/chat/chat_completion_message.rb
  • lib/openai/models/chat/chat_completion_message_function_tool_call.rb
  • lib/openai/models/chat/completion_create_params.rb
  • lib/openai/models/response_format_json_schema.rb
  • lib/openai/models/responses/function_tool.rb
  • lib/openai/models/responses/response.rb
  • lib/openai/models/responses/response_create_params.rb
  • lib/openai/models/responses/response_format_text_config.rb
  • lib/openai/models/responses/response_format_text_json_schema_config.rb
  • lib/openai/models/responses/response_function_tool_call.rb
  • lib/openai/models/responses/response_function_web_search.rb
  • lib/openai/models/responses/response_output_text.rb
  • lib/openai/models/responses/tool.rb
  • lib/openai/resources/beta/threads.rb
  • lib/openai/resources/chat/completions.rb
  • lib/openai/resources/files.rb
  • lib/openai/resources/responses.rb
  • lib/openai/resources/vector_stores/file_batches.rb
  • lib/openai/resources/vector_stores/files.rb
  • lib/openai/resources/webhooks.rb
  • rbi/openai/client.rbi
  • rbi/openai/models/chat/chat_completion_message.rbi
  • rbi/openai/models/chat/chat_completion_message_function_tool_call.rbi
  • rbi/openai/models/chat/completion_create_params.rbi
  • rbi/openai/models/response_format_json_schema.rbi
  • rbi/openai/models/responses/response.rbi
  • rbi/openai/models/responses/response_create_params.rbi
  • rbi/openai/models/responses/response_function_tool_call.rbi
  • rbi/openai/models/responses/response_function_web_search.rbi
  • rbi/openai/models/responses/response_output_text.rbi
  • rbi/openai/resources/chat/completions.rbi
  • rbi/openai/resources/files.rbi
  • rbi/openai/resources/responses.rbi
  • rbi/openai/resources/vector_stores/file_batches.rbi
  • rbi/openai/resources/vector_stores/files.rbi
  • scripts/castiron/README.md
  • scripts/castiron/custom_code_report.py
  • scripts/castiron/test_custom_code_report.py

7 more in the full report.

A changed generated baseline means this report cannot reliably identify which handwritten lines changed.

Inspect the custom-code diff

Download the exact patch produced by this run (requires repository access):

gh run download 33927791253 --repo openai/openai-ruby \
  --name castiron-custom-code-33927791253-1 --dir /tmp/castiron-custom-code-33927791253-1
git apply --stat /tmp/castiron-custom-code-33927791253-1/custom-code.patch
cat /tmp/castiron-custom-code-33927791253-1/custom-code.patch

Or reproduce it from an SDK checkout containing the vendored reporter:

git fetch --no-tags origin 6b9ee8729c3ac429cc93716e8b51bce603de3405 08fcfd1a7f6cdfd4e5af16161c7ba9c0e3122a57
python3 scripts/castiron/custom_code_report.py report \
  --base 6b9ee8729c3ac429cc93716e8b51bce603de3405 \
  --head 08fcfd1a7f6cdfd4e5af16161c7ba9c0e3122a57 --fetch --require-head-hash --public \
  --out /tmp/castiron-custom-code-08fcfd1a7f6c
cat /tmp/castiron-custom-code-08fcfd1a7f6c/custom-code.patch

This is the current full custom patch for mixed files, not an attribution of only the handwritten lines changed by this PR.

Full report and patch

@openai-sdks

openai-sdks Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

OkTest Summary

237/237 SDK tests passed in 9.592s for Ruby SDK PR #624.

Test results — 42 files
Test Result Time
tests/chat-completions-complex-body.test.ts ✅ Passed 177ms
tests/chat-completions-create.test.ts ✅ Passed 217ms
tests/chat-completions-stream.test.ts ✅ Passed 135ms
tests/files-content-binary.test.ts ✅ Passed 151ms
tests/files-create-multipart.test.ts ✅ Passed 154ms
tests/files-list-pagination.test.ts ✅ Passed 148ms
tests/initialize-config.test.ts ✅ Passed 173ms
tests/instance-isolation.test.ts ✅ Passed 185ms
tests/models-list.test.ts ✅ Passed 268ms
tests/responses-background-lifecycle.test.ts ✅ Passed 218ms
tests/responses-body-method-errors.test.ts ✅ Passed 452ms
tests/responses-cancel-timeout.test.ts ✅ Passed 237ms
tests/responses-cancel.test.ts ✅ Passed 231ms
tests/responses-compact-retries.test.ts ✅ Passed 267ms
tests/responses-compact.test.ts ✅ Passed 222ms
tests/responses-create-advanced-stream.test.ts ✅ Passed 143ms
tests/responses-create-advanced.test.ts ✅ Passed 215ms
tests/responses-create-disconnect.test.ts ✅ Passed 970ms
tests/responses-create-errors.test.ts ✅ Passed 263ms
tests/responses-create-malformed-api-responses.test.ts ✅ Passed 150ms
tests/responses-create-retries.test.ts ✅ Passed 324ms
tests/responses-create-stream-failures.test.ts ✅ Passed 141ms
tests/responses-create-stream-timeout.test.ts ✅ Passed 219ms
tests/responses-create-stream-wire.test.ts ✅ Passed 2.348s
tests/responses-create-stream.test.ts ✅ Passed 75ms
tests/responses-create-terminal-states.test.ts ✅ Passed 250ms
tests/responses-create-timeout.test.ts ✅ Passed 220ms
tests/responses-create.test.ts ✅ Passed 219ms
tests/responses-delete.test.ts ✅ Passed 203ms
tests/responses-input-items-errors.test.ts ✅ Passed 177ms
tests/responses-input-items-list.test.ts ✅ Passed 199ms
tests/responses-input-items-options.test.ts ✅ Passed 255ms
tests/responses-input-tokens-count-timeout.test.ts ✅ Passed 278ms
tests/responses-input-tokens-count.test.ts ✅ Passed 222ms
tests/responses-malformed-inputs.test.ts ✅ Passed 2.036s
tests/responses-not-found-errors.test.ts ✅ Passed 286ms
tests/responses-parse.test.ts ✅ Passed 177ms
tests/responses-retrieve-retries.test.ts ✅ Passed 314ms
tests/responses-retrieve.test.ts ✅ Passed 248ms
tests/responses-stored-method-errors.test.ts ✅ Passed 632ms
tests/retry-behavior.test.ts ✅ Passed 3.192s
tests/sdk-error-shape.test.ts ✅ Passed 350ms

View OkTest run #33927535604

SDK merge (b3199cb467ae) · head (08fcfd1a7f6c) · base (6b9ee8729c3a) · OkTest (2b1bdfd25e98)

@HAYDEN-OAI HAYDEN-OAI 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.

Reviewed both changed files and the surrounding SSE decoding, raw Chat stream, and cleanup paths. Explicit base 10 fixes leading-zero retry values while preserving the existing digit-only guard. The regression tests cover decimal metadata and continued delivery through stream_raw for 0, 8, 08, 09, and 010. No substantive findings.

Static review only: Ruby is unavailable in this environment, so I did not run tests or independently reproduce the reported suite results.

@jbeckwith-oai
jbeckwith-oai added this pull request to the merge queue Sep 4, 2026
Merged via the queue into main with commit 9135d15 Sep 4, 2026
22 checks passed
@jbeckwith-oai
jbeckwith-oai deleted the codex/parse-sse-retry-decimal branch September 4, 2026 23:37
@openai-sdks openai-sdks Bot mentioned this pull request Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autoimprove Automated repository-health improvements codex-maintenance Low-risk maintenance changes created by Codex

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants