fix: strip thinking tags from OpenAI-compatible provider responses
Remove leaked thinking/reasoning tags from assistant content to prevent internal reasoning text from being exposed to end users. Fixes #1235
This commit is contained in:
parent
cdbd09bf2f
commit
84a2dc291d
1 changed files with 44 additions and 3 deletions
|
|
@ -350,9 +350,16 @@ func parseResponse(body io.Reader) (*LLMResponse, error) {
|
|||
toolCalls = append(toolCalls, toolCall)
|
||||
}
|
||||
|
||||
// Extract thinking content from content if present (for models like MiniMax)
|
||||
content := choice.Message.Content
|
||||
reasoningContent := choice.Message.ReasoningContent
|
||||
if reasoningContent == "" {
|
||||
content, reasoningContent = extractThinkingTags(content)
|
||||
}
|
||||
|
||||
return &LLMResponse{
|
||||
Content: choice.Message.Content,
|
||||
ReasoningContent: choice.Message.ReasoningContent,
|
||||
Content: content,
|
||||
ReasoningContent: reasoningContent,
|
||||
Reasoning: choice.Message.Reasoning,
|
||||
ReasoningDetails: choice.Message.ReasoningDetails,
|
||||
ToolCalls: toolCalls,
|
||||
|
|
@ -360,8 +367,42 @@ func parseResponse(body io.Reader) (*LLMResponse, error) {
|
|||
Usage: apiResponse.Usage,
|
||||
}, nil
|
||||
}
|
||||
// extractThinkingTags extracts content between
|
||||
// and from the content string.
|
||||
// Returns the content with thinking tags removed and the extracted thinking content.
|
||||
func extractThinkingTags(content string) (string, string) {
|
||||
const thinkOpen = "<think>"
|
||||
const thinkClose = "</think>"
|
||||
|
||||
// Check if content contains thinking tags
|
||||
if !strings.Contains(content, thinkOpen) {
|
||||
return content, ""
|
||||
}
|
||||
|
||||
// Extract thinking content
|
||||
start := strings.Index(content, thinkOpen)
|
||||
end := strings.Index(content, thinkClose)
|
||||
if end <= start {
|
||||
return content, ""
|
||||
}
|
||||
|
||||
thinkingContent := content[start+len(thinkOpen) : end]
|
||||
|
||||
// Remove thinking tags from content
|
||||
var result strings.Builder
|
||||
result.Grow(len(content))
|
||||
|
||||
// Add content before thinking tags
|
||||
result.WriteString(content[:start])
|
||||
|
||||
// Add content after thinking tags
|
||||
if end+len(thinkClose) < len(content) {
|
||||
result.WriteString(content[end+len(thinkClose):])
|
||||
}
|
||||
|
||||
return result.String(), thinkingContent
|
||||
}
|
||||
|
||||
// openaiMessage is the wire-format message for OpenAI-compatible APIs.
|
||||
// It mirrors protocoltypes.Message but omits SystemParts, which is an
|
||||
// internal field that would be unknown to third-party endpoints.
|
||||
type openaiMessage struct {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue