More armoring of decision parsing.

This commit is contained in:
Steve White 2025-01-25 20:56:23 -06:00
parent 36fdd5f00e
commit 4c2adc636b
1 changed files with 22 additions and 9 deletions

View File

@ -180,18 +180,29 @@ Abstract: %s`, criteria, paper.Title, paper.Abstract)
} }
content := llmResp.Choices[0].Message.Content content := llmResp.Choices[0].Message.Content
lines := bytes.Split([]byte(content), []byte("\n"))
if len(lines) < 2 { // Find first line with ACCEPT/REJECT
return nil, fmt.Errorf("invalid response format") var decisionLine string
lines := bytes.Split([]byte(content), []byte("\n"))
for _, line := range lines {
if strings.Contains(strings.ToUpper(string(line)), "ACCEPT") ||
strings.Contains(strings.ToUpper(string(line)), "REJECT") {
decisionLine = string(line)
break
}
}
if decisionLine == "" {
return nil, fmt.Errorf("no decision found in response. Full response:\n%s", content)
} }
// Clean and normalize decision // Clean and normalize decision
rawDecision := string(bytes.TrimSpace(lines[0])) rawDecision := strings.TrimSpace(decisionLine)
// Remove any non-alphabetic characters from start/end // Remove "DECISION:" prefix if present and trim non-alphabetic characters
cleanDecision := strings.TrimFunc(rawDecision, func(r rune) bool { cleanDecision := strings.TrimPrefix(rawDecision, "DECISION:")
return !unicode.IsLetter(r) cleanDecision = strings.TrimFunc(cleanDecision, func(r rune) bool {
return !unicode.IsLetter(r) && !unicode.IsNumber(r)
}) })
// Normalize case and check for valid decision // Normalize case and check for valid decision
@ -203,10 +214,12 @@ Abstract: %s`, criteria, paper.Title, paper.Abstract)
case strings.HasPrefix(upperDecision, "REJECT"): case strings.HasPrefix(upperDecision, "REJECT"):
decision = "REJECT" decision = "REJECT"
default: default:
return nil, fmt.Errorf("invalid decision value: %q (cleaned: %q)", rawDecision, cleanDecision) return nil, fmt.Errorf("invalid decision value: %q (cleaned: %q). Full response:\n%s",
rawDecision, cleanDecision, content)
} }
explanation := string(bytes.TrimSpace(bytes.Join(lines[1:], []byte("\n")))) // Get explanation as everything after the decision line
explanation := strings.TrimSpace(strings.Replace(content, decisionLine, "", 1))
return &decisionResult{ return &decisionResult{
Decision: decision, Decision: decision,