fix(client): support vLLM "reasoning" field for thinking blocks
All checks were successful
continuous-integration/drone/push Build is passing

vLLM sends thinking content in a "reasoning" delta field, unlike
DeepSeek which uses "reasoning_content". Check both field names so
thinking blocks render for vLLM-hosted models like qwen3.6-27b-thinking.

Also update client tests to exercise thinking output and skip by default
so they don't run in Drone CI (require live LLM API).
This commit is contained in:
2026-04-30 21:55:05 -04:00
parent 5d5f10b2d8
commit c51c0ab070
2 changed files with 37 additions and 18 deletions

View File

@@ -115,15 +115,19 @@ func (c *Client) SendMessage(ctx context.Context, chatMessages []*store.Message,
if len(chunk.Choices) > 0 {
delta := chunk.Choices[0].Delta
// Check Thinking
if thinkingField, found := delta.JSON.ExtraFields["reasoning_content"]; found {
var thinkingContent string
if err := json.Unmarshal([]byte(thinkingField.Raw()), &thinkingContent); err != nil {
return respContent, fmt.Errorf("thinking unmarshal error: %w", err)
} else if thinkingContent != "" {
msgStats.RecordFirstToken()
sendUpdate = true
msgChunk.Thinking = ptr.Of(thinkingContent)
// Check Thinking - Support both "reasoning_content" (DeepSeek)
// and "reasoning" (vLLM) field names.
for _, thinkingKey := range []string{"reasoning_content", "reasoning"} {
if thinkingField, found := delta.JSON.ExtraFields[thinkingKey]; found {
var thinkingContent string
if err := json.Unmarshal([]byte(thinkingField.Raw()), &thinkingContent); err != nil {
return respContent, fmt.Errorf("thinking unmarshal error: %w", err)
} else if thinkingContent != "" {
msgStats.RecordFirstToken()
sendUpdate = true
msgChunk.Thinking = ptr.Of(thinkingContent)
}
break
}
}