| 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 |
| } |
|
|