Chat Completions 拒絕回應不再靜默丟失

過去在 Chat Completions 模型中,當模型拒絕回答時,API 返回的 message.refusal(非串流)或 delta.refusal(串流)欄位被忽略。這導致 AI SDK 僅返回空文字並標記為 stop 結束原因,用戶無法得知拒絕的原因。

在 @ai-sdk/[email protected] 中,拒絕文字現在會在 generateText 和 streamText 結果中作為文字內容輸出。如果 API 同時返回內容與拒絕資訊,兩者都會被呈現。

帶有 stop 結束原因的拒絕回應,現在會被報告為 content-filter 結束原因。此行為調整旨在與 Anthropic 供應商及 Responses API 的處理方式保持一致。

Responses API 解析錯誤修復

Responses API 在模型拒絕請求時,會返回 refusal 內容部分而非 output_text。舊版程式碼因回應結構驗證失敗,導致非串流呼叫拋出 APICallError(Invalid JSON response),而串流事件則被丟棄並產生空文字。

更新後,系統能正確解析 refusal 內容部分與相關串流事件。拒絕解釋會被呈現為文字,結束原因映射為 content-filter。

若回應中同時包含客戶端函數調用,結束原因將保持為 tool-calls,確保工具仍能正常執行。

Logprobs 數據收集範圍擴大

@ai-sdk/openai 模組現在會包含拒絕回應的 logprobs。過去僅讀取 logprobs.content,導致 providerMetadata.openai.logprobs 在拒絕情況下為空或缺失。現在內容與拒絕的 logprobs 會按發出順序一併包含。

在 streamText 中,logprobs 現在會跨所有區塊收集數據。此前僅報告最後一個串流區塊的 logprobs,現在則包含每個串出 token 的數據。明確為空的 logprobs 仍報告為空陣列。

若拒絕訊息與 finish_reason 在同一個串流區塊中到達,該回應將被標記為 content-filter 結束原因,而非 stop。

OpenAI Compatible 供應商行為對齊

@ai-sdk/openai-compatible 模組也進行了修正。過去透過 createOpenAICompatible 使用的 OpenAI 服務會忽略拒絕文字,導致返回空的 stop 回應。現在拒絕文字會在內容文字之後作為文字內容返回。

非字串類型的拒絕值(例如某些伺服器返回的 refusal: false)將被忽略,而不會導致回應失敗。

Azure 模型目錄重構

此次更新還包含內部重構,將 Azure 模型 ID 邏輯移至一個宣告功能與供應商選項的模型目錄中。系統會從該目錄生成供應商功能文件。

OpenAI 目錄被內部導出以供 Azure 重複使用。此變更僅涉及內部架構調整,請求行為保持不變。