Skip to content

Fix runTools readable stream round trip tool results#1986

Open
momomuchu wants to merge 2 commits into
openai:mainfrom
momomuchu:fix/preserve-tool-results-stream-roundtrip
Open

Fix runTools readable stream round trip tool results#1986
momomuchu wants to merge 2 commits into
openai:mainfrom
momomuchu:fix/preserve-tool-results-stream-roundtrip

Conversation

@momomuchu

Copy link
Copy Markdown

Summary

When a streaming runTools() run is serialized with toReadableStream() and reconstructed with fromReadableStream(), tool result messages were lost. The proxied runner kept assistant messages rebuilt from chunks, but missed { role: 'tool' } messages and the related functionToolCallResult event.

Root cause

The readable stream protocol only wrote raw ChatCompletionChunk lines. Local tool result messages are added by the runner after tool execution, so they were never present in the serialized stream.

Fix

ChatCompletionStreamingRunner.toReadableStream() now keeps normal chunk lines unchanged and adds tool result messages as a small envelope line shaped { type: 'message', message }. fromReadableStream() consumes that envelope as a real message and uses it as a completion boundary. The stream end guard now accepts a stream that ends after a tool message while preserving request ended without sending any chunks for truly empty streams.

Compatibility

Old raw chunk streams still reconstruct the same way. ChatCompletionChunk has no top level type field, so an old chunk is not mistaken for a message envelope. Assistant messages are still rebuilt from chunks, so this does not duplicate assistant messages.

Scope

The PR template warns that this SDK is generated. This change is confined to src/lib, which is hand written and not generator owned. Tests are confined to tests/lib.

Tests

./scripts/test tests/lib tests/api-resources

682 passed. No failures.

Fixes #1060

@momomuchu momomuchu requested a review from a team as a code owner July 7, 2026 14:29

@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: 6e82c4d23b

ℹ️ 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 src/lib/ChatCompletionStreamingRunner.ts Outdated
@HAYDEN-OAI

Copy link
Copy Markdown
Contributor

pushed a follow-up in 91feb7d7 that preserves normalized tool-call ids across the readable-stream relay and encodes tool-result records as legacy-safe empty chunks, so older fromReadableStream() consumers do not crash. i also added regressions for empty-id round trips and legacy chunk readers.

verified with pnpm exec jest tests/lib/ChatCompletionRunFunctions.test.ts --runInBand --verbose --no-cache, pnpm exec tsc --noEmit, and pnpm build.

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.

functionCallResult never get's called in the frontend with ChatCompletionStream

2 participants