OpenAIConfig.stream_options is a user passthrough field, and _openai_create_kwargs copies it into the body on both paths. So OpenAIConfig(stream_options={'include_usage': False}) on a non-streaming request puts stream_options on a non-streaming body, where the API documents it as valid only with stream: true. The SDK will not stop it; the non-streaming overload accepts the parameter and sends it.
Combined with the streaming path forcing include_usage: True, a caller's stream_options is honoured on the path where the API says it is invalid and overridden on the path where it is valid. The field's docstring in typing.py also offers include_usage as its example, which is the one key a caller can no longer set.
Neither reference has a deliberate position (Go does not strip StreamOptions with the other managed fields, and JS spreads unrecognised config keys into the body wholesale) so there is nothing to port.
Existing tests would not catch it: the non-streaming test asserts stream_options is absent, but its fixture sets none, so it pins only that the plugin adds nothing.
Unverified: whether a real endpoint 400s or silently ignores stream_options on a non-streaming call. That decides whether this is a latent 400 or just a dirty request body, and it is worth confirming before choosing a fix.
OpenAIConfig.stream_optionsis a user passthrough field, and_openai_create_kwargscopies it into the body on both paths. SoOpenAIConfig(stream_options={'include_usage': False})on a non-streaming request putsstream_optionson a non-streaming body, where the API documents it as valid only withstream: true. The SDK will not stop it; the non-streaming overload accepts the parameter and sends it.Combined with the streaming path forcing
include_usage: True, a caller'sstream_optionsis honoured on the path where the API says it is invalid and overridden on the path where it is valid. The field's docstring intyping.pyalso offersinclude_usageas its example, which is the one key a caller can no longer set.Neither reference has a deliberate position (Go does not strip
StreamOptionswith the other managed fields, and JS spreads unrecognised config keys into the body wholesale) so there is nothing to port.Existing tests would not catch it: the non-streaming test asserts
stream_optionsis absent, but its fixture sets none, so it pins only that the plugin adds nothing.Unverified: whether a real endpoint 400s or silently ignores
stream_optionson a non-streaming call. That decides whether this is a latent 400 or just a dirty request body, and it is worth confirming before choosing a fix.