|
|
package functions |
|
|
|
|
|
import ( |
|
|
"strings" |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func ExtractReasoning(content string) (reasoning string, cleanedContent string) { |
|
|
if content == "" { |
|
|
return "", content |
|
|
} |
|
|
|
|
|
var reasoningParts []string |
|
|
var cleanedParts []string |
|
|
remaining := content |
|
|
|
|
|
|
|
|
tagPairs := []struct { |
|
|
start string |
|
|
end string |
|
|
}{ |
|
|
{"<thinking>", "</thinking>"}, |
|
|
{"<think>", "</think>"}, |
|
|
} |
|
|
|
|
|
|
|
|
lastPos := 0 |
|
|
|
|
|
for { |
|
|
|
|
|
earliestStart := -1 |
|
|
earliestEnd := -1 |
|
|
isUnclosed := false |
|
|
var matchedTag struct { |
|
|
start string |
|
|
end string |
|
|
} |
|
|
|
|
|
for _, tagPair := range tagPairs { |
|
|
startIdx := strings.Index(remaining[lastPos:], tagPair.start) |
|
|
if startIdx == -1 { |
|
|
continue |
|
|
} |
|
|
startIdx += lastPos |
|
|
|
|
|
|
|
|
endIdx := strings.Index(remaining[startIdx+len(tagPair.start):], tagPair.end) |
|
|
if endIdx == -1 { |
|
|
|
|
|
if earliestStart == -1 || startIdx < earliestStart { |
|
|
earliestStart = startIdx |
|
|
earliestEnd = len(remaining) |
|
|
isUnclosed = true |
|
|
matchedTag = tagPair |
|
|
} |
|
|
continue |
|
|
} |
|
|
endIdx += startIdx + len(tagPair.start) |
|
|
|
|
|
|
|
|
if earliestStart == -1 || startIdx < earliestStart { |
|
|
earliestStart = startIdx |
|
|
earliestEnd = endIdx + len(tagPair.end) |
|
|
isUnclosed = false |
|
|
matchedTag = tagPair |
|
|
} |
|
|
} |
|
|
|
|
|
if earliestStart == -1 { |
|
|
|
|
|
if lastPos < len(remaining) { |
|
|
cleanedParts = append(cleanedParts, remaining[lastPos:]) |
|
|
} |
|
|
break |
|
|
} |
|
|
|
|
|
|
|
|
if earliestStart > lastPos { |
|
|
cleanedParts = append(cleanedParts, remaining[lastPos:earliestStart]) |
|
|
} |
|
|
|
|
|
|
|
|
reasoningStart := earliestStart + len(matchedTag.start) |
|
|
|
|
|
|
|
|
var reasoningEnd int |
|
|
if isUnclosed { |
|
|
|
|
|
reasoningEnd = len(remaining) |
|
|
} else { |
|
|
|
|
|
reasoningEnd = earliestEnd - len(matchedTag.end) |
|
|
} |
|
|
if reasoningEnd > reasoningStart { |
|
|
reasoningContent := strings.TrimSpace(remaining[reasoningStart:reasoningEnd]) |
|
|
if reasoningContent != "" { |
|
|
reasoningParts = append(reasoningParts, reasoningContent) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
lastPos = earliestEnd |
|
|
} |
|
|
|
|
|
|
|
|
reasoning = strings.Join(reasoningParts, "\n\n") |
|
|
|
|
|
cleanedContent = strings.Join(cleanedParts, "") |
|
|
|
|
|
return reasoning, cleanedContent |
|
|
} |
|
|
|