Skip to content

[pull] main from openai:main - #191

Merged
pull[bot] merged 7 commits into
Pyrex77:mainfrom
openai:main
Sep 28, 2026
Merged

pull[bot] merged 7 commits into
Pyrex77:mainfrom
openai:main

Conversation

@pull

@pull pull Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

markstuart-oai and others added 7 commits September 28, 2026 04:56
When two transcript groupers observe the same Live dispatcher, callers
must be able to detach and close one without stopping the other or
losing the event stream. The existing grouper tests covered its own
listeners and timers but did not exercise an attached connection.

This tests both sync and async clients over a real local WebSocket. It
checks that the first grouper cancels its active timer, typed and
wildcard observers keep receiving the original values and future
metadata, the second grouper continues accumulating, and the same socket
accepts a post-disposal update. The peer waits for explicit caller
teardown. Tests only; no generated or API changes.

Validation:
- 238 Live tests passed on Pydantic 2.12.5 and 238 on 1.10.26.
- After typing the close callbacks and checking only event IDs present
on the wire: 14 socket-role and grouper tests pass; Pyright reports 0
errors on the affected file.
- Repository-configured `mypy .` passes across 1,920 source files; Ruff
check, format and diff checks pass.
…ends (#3978)

An empty Realtime manager queue was replaced on connect, losing its
configured byte limit and later messages. A typed or queued send could
also be replayed on reconnect even after reaching the server. Preserve
the manager's queue and release only attempted writes on failure or
cancellation; never-attempted messages remain in order. Other endpoints
retain the shared queue's existing defaults.

Six sync/async real-socket regressions fail on the base and pass with
this change, covering empty queues and interrupted pre-open/direct
sends. A focused cancellation regression verifies in-flight bounds and
retained messages. Validation: 456 affected tests per Pydantic 1/2, 45
final queue/Realtime tests per version, Ruff, mypy (1,865 files),
Pyright, and the trusted custom-code check (7,766/10,000).
#3979)

Adds real WebSocket coverage for existing Realtime recovery behavior in
synchronous and asynchronous clients.

- Direct `recv`, no callback, caller abort, nonrecoverable close and
clean close stop without another upgrade.
- Repeated typed admission errors followed by 1011 consume the retry
budget: two retries, three sockets. A successful upgrade alone does not
reset it.
- OpenAI and Azure refresh caller-provided credentials on the
replacement and preserve the connection's path, query, headers and
disabled compression. Azure bearer mode never also sends an API key.
- Cancelling a pending async receive leaves the next event and the
socket usable.

Tests only; no source, signatures, defaults, dependencies or generated
code changed. Uses the existing real server fixture and fake
credentials. The new file applies independently of the in-flight queue
fix (#3978).

Verified 179/179 relevant WebSocket, redirects and send-queue checks on
each of Pydantic 1 and 2; Ruff check/format and git diff pass. Trusted
budget unchanged at 7746/10000.
…lay (#3980)

If a Live connection opened with an empty manager queue, iterator
recovery lost the caller's queued messages and byte budget. A typed
command could also be sent again after the first socket actually
received it but its send raised. Keep the passed queue even when empty
and drop only the attempted message on a failed send/flush, leaving
unattempted messages ordered. This matches the merged Realtime handling.

Primary, fork and sideband fixes are separate commits for review. No
startup, auth, default reconnect, imports or public method signatures
change. Direct send errors still raise; queued flush failures still log
the existing warning. The Live helper notes describe the recovery and
recording-error policy.

Validation:
- Baseline: 337 Live/redirect tests pass under both Pydantic 1 and 2.
- Reproduced all 18 queue/replay failures using actual loopback wire
delivery, then 42 role tests pass, including per-role
error/unknown-event/close ordering and helper disposal.
- Final 399 Live, protected dial, Realtime and send-queue tests pass in
each Pydantic lane; Ruff and full SDK Mypy (1,865 source files) pass.
- Trusted main budget/isolation pass: 7,826/10,000 with unchanged
generated snapshot. Independent review found only the queued-error doc
clarification, which is included.
…3981)

The opt-in Responses WebSocket accumulator currently retains selected
text/tool fields but loses response metadata, streamed logprobs,
citations and non-text parts. This adds `detailed_snapshot()`, an
independent mutable view of observed fields and sparse indexed
output/content/annotation rows. Existing immutable, hashable
`snapshot()`, raw events, and the exact server terminal response keep
their contracts.

Done events replace supplied logprobs and whole part/item/response
events replace the relevant projections. Missing and null are preserved,
and unknown parts or tool fields remain provisional data instead of
fabricated validated final models. Annotations only enrich a matching
item on the bound lane; they cannot bind a turn or retire an unrelated
item. The helper still never reads, sends, runs tools or changes
sockets. Handwritten helper, docs and tests only.

Validation:
- Before change: 12 new real-wire tests failed. Review regressions
reproduced: 8 failures (foreign or omitted annotation, null/missing
content).
- Current accumulator/session suite: 438 passed on each of Pydantic 1
and 2, sync and async local WebSockets.
- SDK mypy: 1,865 files passed; Ruff and formatting pass.
- Base's verified custom-code check: unchanged 7,826 / 10,000; no schema
or generator change.
Raw TLS failures can escape HTTPX2's exception normalization and bypass
the SDK's retry and connection-error handling introduced in 3.14.1.
Treat `ssl.SSLError` and `anyio.EndOfStream` as connection errors until
the upstream mappings are fixed, with a short comment linking
pydantic/httpx2#854.

Request failures now honor the retry budget and raise
`APIConnectionError` on exhaustion. Streaming failures are wrapped
without replaying the stream. Generic application exceptions still
propagate unchanged.

Closes #3969.

Validation:
- Client, streaming, and HTTPX2 suites: 368 passed, 22 skipped.
- Regression coverage includes sync/async recovery, exhaustion, disabled
retries, and failures before/after the first streaming event.
- Ruff, targeted mypy, and `git diff --check` passed.
- Tests used frozen dependencies because `uv run --locked` reported an
existing lockfile mismatch; proxy environment variables were unset for
the offline tests.
- Pyright could not run because the repository requires Node 22.22.3 and
the active Node is 18.19.1.
Automated Release PR
---


##
[3.20.0](v3.19.2...v3.20.0)
(2026-09-28)


### Features

* **api:** add Agents credential and session options
([#3967](#3967))
([bb68198](bb68198))
* **api:** add Cyber access programs to Responses
([#3956](#3956))
([09c5b6f](09c5b6f))
* **responses:** opt in to incremental WebSocket text and tool snapshots
([#3973](#3973))
([d0207b4](d0207b4))
* **responses:** preserve detailed WebSocket accumulator snapshots
([#3981](#3981))
([a380cf2](a380cf2))


### Bug Fixes

* **client:** retry unmapped TLS transport errors
([#3982](#3982))
([0d35a26](0d35a26))
* **live:** avoid hangs at fractional transcript grouping deadlines
([#3970](#3970))
([4ef4129](4ef4129))
* **live:** keep query parameters out of WebSocket endpoint paths
([#3972](#3972))
([f9c458b](f9c458b))
* **live:** preserve caller queues and prevent uncertain WebSocket
replay ([#3980](#3980))
([80e9686](80e9686))
* **realtime:** preserve base URL queries in WebSocket upgrades
([#3971](#3971))
([f7bd4a7](f7bd4a7))
* **realtime:** retain configured queues without replaying attempted
sends ([#3978](#3978))
([a52805c](a52805c))


### Chores

* **api:** clarify documented API error responses
([#3965](#3965))
([384fee3](384fee3))
* **api:** document batch error responses
([#3961](#3961))
([6e4a79c](6e4a79c))
* **api:** document files and uploads error responses
([#3960](#3960))
([a9d727f](a9d727f))
* **api:** document fine-tuning and model errors
([#3964](#3964))
([5d4003c](5d4003c))
* **api:** document Responses not-found errors
([#3959](#3959))
([63099e7](63099e7))
* **api:** document stored chat completion errors
([#3963](#3963))
([a73fe0c](a73fe0c))

---
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>
@pull pull Bot locked and limited conversation to collaborators Sep 28, 2026
@pull pull Bot added the ⤵️ pull label Sep 28, 2026
@pull
pull Bot merged commit 68b173a into Pyrex77:main Sep 28, 2026
1 of 2 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants