github vercel/ai @ai-sdk/openai@4.0.110

latest releases: @ai-sdk/zai@3.0.48, @ai-sdk/workflow-harness@1.0.175, @ai-sdk/workflow@2.0.96...
one hour ago

Patch Changes

  • c6efa4b: Refactor Azure model ID logic into a model catalog that declares capabilities and provider options, and generate provider capability documentation from it. Export the OpenAI catalog internally for Azure to reuse. Request behavior is unchanged.

  • f6dbf04: fix(openai): surface Chat Completions refusals as text content

    The Chat Completions model ignored message.refusal (non-streaming) and delta.refusal (streaming). When the model refused to answer, content was null, so the AI SDK returned empty text with a stop finish reason and silently dropped the refusal. Refusal text is now emitted as text content in both generateText and streamText results, and it is emitted in addition to content when the API returns both. A refusal with a stop finish reason is now reported as a content-filter finish reason, matching the Anthropic provider and the Responses API.

  • 646a7e3: fix(openai,openai-compatible): surface refusal logprobs and openai-compatible refusals

    @ai-sdk/openai: Chat Completions responses that contain a refusal can return logprobs.refusal next to logprobs.content. The provider previously read only logprobs.content, so providerMetadata.openai.logprobs was empty or missing for refusals. Refusal logprobs are now included in emission order (content logprobs followed by refusal logprobs) in both generateText and streamText.

    Streaming logprobs are now collected across all chunks in streamText: previously only the logprobs of the last streamed chunk were reported. This applies to content logprobs as well, so providerMetadata.openai.logprobs now contains the logprobs of every streamed token instead of only the last chunk's tokens. Explicitly empty logprobs (logprobs: { content: [], refusal: null }) are reported as an empty array, as before.

    A refusal that arrives in the same streamed chunk as the finish_reason is now taken into account: such a response is reported with a content-filter finish reason instead of stop.

    @ai-sdk/openai-compatible: Chat Completions responses that carry message.refusal (non-streaming) or delta.refusal (streaming) were ignored, so providers such as OpenAI served through createOpenAICompatible lost the refusal text and reported an empty stop response. Refusals are now returned as text content after any content text, and a non-empty refusal with a stop finish reason is reported as a content-filter finish reason. This also applies when the refusal and the finish reason arrive in the same streamed chunk. Non-string refusals (for example refusal: false from servers that use booleans) are ignored instead of failing the response.

  • 6b97088: fix(openai): handle refusal content parts in the Responses API

    The Responses API returns a refusal content part instead of output_text when the model declines a request. The response schema rejected these parts, so non-streaming calls failed with an APICallError ("Invalid JSON response"), and streamed response.refusal.delta / response.refusal.done events were dropped, producing empty text. Refusal content parts and stream events are now parsed: the refusal explanation is surfaced as text and the finish reason is mapped to content-filter. When the response also contains a client-side function call, the finish reason stays tool-calls so the tools are still executed.

Don't miss a new ai release

NewReleases is sending notifications on new releases.