Skip to content

fix(examples): avoid extra requests for empty tool calls - #2672

Merged
HAYDEN-OAI merged 1 commit into
mainfrom
codex/raw-tool-empty-call-array
Sep 7, 2026
Merged

fix(examples): avoid extra requests for empty tool calls#2672
HAYDEN-OAI merged 1 commit into
mainfrom
codex/raw-tool-empty-call-array

Conversation

@HAYDEN-OAI

Copy link
Copy Markdown
Contributor

Summary

  • Stop the raw tool-calling example when the collected tool-call array is empty, using the same length check as the SDK's tool runner.
  • Keep the check after the stream is fully reduced. The reducer, model, streaming delay, output, SDK, generated code, and dependencies are unchanged.
  • Extend the existing redirected-output fixture to cover omitted and empty tool-call arrays, both for direct answers and after a valid tool round trip.

Reproduction

A completed assistant response with finish_reason: 'stop' and tool_calls: [] leaves an empty array in the example's collected message. Because an empty array is truthy, the old guard falls through, executes zero tools, and starts another completion request.

The actual example sends an unwanted second POST for a direct answer, or a third POST after one valid tool round trip. Omitted tool calls correctly stop after one or two requests. The reproduction server rejects the first unwanted request with a non-retryable HTTP 400, so the failure is bounded and does not rely on a process timeout. Repeated empty-array answers could otherwise keep the request loop running.

Validation

  • Expand the existing executable fixture from three to six cases. Against the unchanged example, the two empty-array regressions fail their exact request-count assertions while four controls pass. All six pass afterward on exact Node 22.0.0, Node 24.19.0, and Node 26.7.0.
  • Execute the actual example against the built public SDK in four scenarios on each runtime: all 12 checks pass with exact request counts 1, 1, 2, 2, natural successful exits, and final text printed once.
  • Fragmented function arguments, tool-call IDs, and tool results remain unchanged; both legacy function examples retain their redirected-output controls.
  • Full canonical handwritten suite: 7,887 tests pass across 208 files. CJS/ESM build and imports, formatting/lint, pinned TypeScript 6, and whitespace checks pass.
  • Independent adversarial review found no remaining issues. The guard remains after complete stream reduction, preserving non-empty tool calls and avoiding changes to the custom reducer.

The generated suite and remaining ecosystem/packaging checks run in CI.

@HAYDEN-OAI
HAYDEN-OAI requested a review from a team as a code owner September 7, 2026 01:07
@openai-sdks

openai-sdks Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

OkTest Summary

237/237 SDK tests passed in 10.653s for Node SDK PR #2672.

Test results — 42 files
Test Result Time
tests/chat-completions-complex-body.test.ts ✅ Passed 175ms
tests/chat-completions-create.test.ts ✅ Passed 240ms
tests/chat-completions-stream.test.ts ✅ Passed 132ms
tests/files-content-binary.test.ts ✅ Passed 180ms
tests/files-create-multipart.test.ts ✅ Passed 150ms
tests/files-list-pagination.test.ts ✅ Passed 150ms
tests/initialize-config.test.ts ✅ Passed 174ms
tests/instance-isolation.test.ts ✅ Passed 112ms
tests/models-list.test.ts ✅ Passed 175ms
tests/responses-background-lifecycle.test.ts ✅ Passed 245ms
tests/responses-body-method-errors.test.ts ✅ Passed 314ms
tests/responses-cancel-timeout.test.ts ✅ Passed 242ms
tests/responses-cancel.test.ts ✅ Passed 227ms
tests/responses-compact-retries.test.ts ✅ Passed 235ms
tests/responses-compact.test.ts ✅ Passed 288ms
tests/responses-create-advanced-stream.test.ts ✅ Passed 107ms
tests/responses-create-advanced.test.ts ✅ Passed 175ms
tests/responses-create-disconnect.test.ts ✅ Passed 1.178s
tests/responses-create-errors.test.ts ✅ Passed 211ms
tests/responses-create-malformed-api-responses.test.ts ✅ Passed 130ms
tests/responses-create-retries.test.ts ✅ Passed 244ms
tests/responses-create-stream-failures.test.ts ✅ Passed 205ms
tests/responses-create-stream-timeout.test.ts ✅ Passed 2.154s
tests/responses-create-stream-wire.test.ts ✅ Passed 2.609s
tests/responses-create-stream.test.ts ✅ Passed 116ms
tests/responses-create-terminal-states.test.ts ✅ Passed 236ms
tests/responses-create-timeout.test.ts ✅ Passed 243ms
tests/responses-create.test.ts ✅ Passed 231ms
tests/responses-delete.test.ts ✅ Passed 198ms
tests/responses-input-items-errors.test.ts ✅ Passed 186ms
tests/responses-input-items-list.test.ts ✅ Passed 172ms
tests/responses-input-items-options.test.ts ✅ Passed 123ms
tests/responses-input-tokens-count-timeout.test.ts ✅ Passed 251ms
tests/responses-input-tokens-count.test.ts ✅ Passed 245ms
tests/responses-malformed-inputs.test.ts ✅ Passed 2.176s
tests/responses-not-found-errors.test.ts ✅ Passed 260ms
tests/responses-parse.test.ts ✅ Passed 223ms
tests/responses-retrieve-retries.test.ts ✅ Passed 258ms
tests/responses-retrieve.test.ts ✅ Passed 280ms
tests/responses-stored-method-errors.test.ts ✅ Passed 613ms
tests/retry-behavior.test.ts ✅ Passed 3.185s
tests/sdk-error-shape.test.ts ✅ Passed 268ms

View OkTest run #34071979138

SDK merge (cfaeae919511) · head (0946565a07f2) · base (fdb038e21509) · OkTest (2b1bdfd25e98)

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 7, 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-07T01:08:56.322169Z 0946565 PR opened
🔒 Security Review Completed 2026-09-07T01:09:33.094428Z 0946565 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 7, 2026

Copy link
Copy Markdown
Contributor

Castiron custom code

✅ No new custom-code files detected.

32 mixed files remain; 0 existing customizations changed.

Compared fdb038e215090946565a07f2. Generated baselines verified.

32 existing customizations unchanged
  • api.md
  • scripts/castiron/README.md
  • scripts/castiron/custom_code_report.py
  • scripts/castiron/test_custom_code_report.py
  • src/client.ts
  • src/resources/audio/transcriptions.ts
  • src/resources/audio/translations.ts
  • src/resources/beta/assistants.ts
  • src/resources/beta/beta.ts
  • src/resources/beta/index.ts
  • src/resources/beta/responses/internal-base.ts
  • src/resources/beta/responses/responses.ts
  • src/resources/beta/threads/index.ts
  • src/resources/beta/threads/runs/index.ts
  • src/resources/beta/threads/runs/runs.ts
  • src/resources/beta/threads/threads.ts
  • src/resources/chat/completions/completions.ts
  • src/resources/chat/completions/index.ts
  • src/resources/conversations/index.ts
  • src/resources/embeddings.ts
  • src/resources/files.ts
  • src/resources/fine-tuning/checkpoints/permissions.ts
  • src/resources/images.ts
  • src/resources/responses/internal-base.ts
  • src/resources/responses/responses.ts
  • src/resources/skills/skills.ts
  • src/resources/skills/versions/versions.ts
  • src/resources/vector-stores/file-batches.ts
  • src/resources/vector-stores/files.ts
  • src/resources/webhooks/index.ts
  • src/resources/webhooks/webhooks.ts
  • tests/lib/data-residency.test.ts

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 34071995510 --repo openai/openai-node \
  --name castiron-custom-code-34071995510-1 --dir /tmp/castiron-custom-code-34071995510-1
git apply --stat /tmp/castiron-custom-code-34071995510-1/custom-code.patch
cat /tmp/castiron-custom-code-34071995510-1/custom-code.patch

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

git fetch --no-tags origin fdb038e21509264bcdf81741a40988dd694188b1 0946565a07f2537088727f6fc044fdcbb6f53b1f
python3 scripts/castiron/custom_code_report.py report \
  --base fdb038e21509264bcdf81741a40988dd694188b1 \
  --head 0946565a07f2537088727f6fc044fdcbb6f53b1f --fetch --require-head-hash --public \
  --out /tmp/castiron-custom-code-0946565a07f2
cat /tmp/castiron-custom-code-0946565a07f2/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

@markstuart-oai markstuart-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.

Independently reproduced the base example's unwanted second/third requests for completed empty tool-call arrays. This guard matches the SDK runner and stays after full stream reduction; it is the simplest correct fix without changing the reducer or introducing another abstraction. No correctness, security, or structural findings.

Verified the actual example through the built public SDK on Node 22.0.0, 24.20.0, and 26.7.0: omitted/empty calls terminate directly and after a tool round trip with exact counts 1/1/2/2, natural exits, complete output, and preserved fragmented arguments/IDs/results. Five additional error-path checks preserve failures without extra requests. The six-case regression fixture passes on all three runtimes, including both legacy controls; its HTTP 400 bounds unwanted requests without relying on timeout. All 41 runner tests, CJS/ESM build/import checks, TypeScript 6, lint, and diff checks pass.

Validation limit: used copied local dependencies after registry installation failed; stopped the broader handwritten run after failures outside this patch. No full-suite or generated/ecosystem-suite pass is claimed.

@jbeckwith-oai jbeckwith-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 exact head 0946565. Treating an empty tool_calls array as terminal matches the SDK runner and prevents unintended follow-up completions while preserving real tool-call rounds. The fixture bounds extra requests with an explicit 400 and covers omitted/empty calls both initially and after a tool round. CI is green and there are no unresolved threads. No in-scope findings.

@HAYDEN-OAI
HAYDEN-OAI added this pull request to the merge queue Sep 7, 2026
Merged via the queue into main with commit be292d3 Sep 7, 2026
38 checks passed
@HAYDEN-OAI
HAYDEN-OAI deleted the codex/raw-tool-empty-call-array branch September 7, 2026 18:08
@openai-sdks openai-sdks Bot mentioned this pull request Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants