Neither chat path sets finish_reason or finish_message, so every response reports None no matter how the model stopped. _generate reads the finish reason only to write a debug log and then discards it, while _generate_stream never reads it at all.
Refusals are worse than absent: nothing in the plugin reads refusal, so a refusal-only message (no content, no tool calls) raises ValueError: Unable to determine content part instead of returning a blocked response.
Go maps the reason with a provider-aware switch that also covers xAI's end_turn and model_context_window_exceeded and DeepSeek's insufficient_system_resource, and sets the finish message from refusal and from the error object a gateway attaches to a failing choice. JS maps the reason but does not read refusal either (tracked for JS in #6165).
Neither chat path sets
finish_reasonorfinish_message, so every response reportsNoneno matter how the model stopped._generatereads the finish reason only to write a debug log and then discards it, while_generate_streamnever reads it at all.Refusals are worse than absent: nothing in the plugin reads
refusal, so a refusal-only message (no content, no tool calls) raisesValueError: Unable to determine content partinstead of returning a blocked response.Go maps the reason with a provider-aware switch that also covers xAI's
end_turnandmodel_context_window_exceededand DeepSeek'sinsufficient_system_resource, and sets the finish message fromrefusaland from the error object a gateway attaches to a failing choice. JS maps the reason but does not readrefusaleither (tracked for JS in #6165).