fix(translator): emit message_start on first chunk regardless of role field

Some OpenAI-compatible providers (like GitHub Copilot) may send tool_calls
in the first streaming chunk without including the role field. The previous
implementation only emitted message_start when the first chunk contained
role="assistant", causing Anthropic protocol violations when tool calls
arrived first.

This fix ensures message_start is always emitted on the very first chunk,
preventing 'content_block_start before message_start' errors in clients
that strictly validate Anthropic SSE event ordering.
This commit is contained in:
Thong Van
2025-12-16 13:01:09 +07:00
parent 5a812a1e93
commit f4007f53ba

View File

@@ -128,9 +128,10 @@ func convertOpenAIStreamingChunkToAnthropic(rawJSON []byte, param *ConvertOpenAI
param.CreatedAt = root.Get("created").Int() param.CreatedAt = root.Get("created").Int()
} }
// Check if this is the first chunk (has role) // Emit message_start on the very first chunk, regardless of whether it has a role field.
// Some providers (like Copilot) may send tool_calls in the first chunk without a role field.
if delta := root.Get("choices.0.delta"); delta.Exists() { if delta := root.Get("choices.0.delta"); delta.Exists() {
if role := delta.Get("role"); role.Exists() && role.String() == "assistant" && !param.MessageStarted { if !param.MessageStarted {
// Send message_start event // Send message_start event
messageStart := map[string]interface{}{ messageStart := map[string]interface{}{
"type": "message_start", "type": "message_start",