| 764 | } |
| 765 | |
| 766 | func parseMemoryExtractorCandidates( |
| 767 | output string, |
| 768 | turn memcontract.TurnRecord, |
| 769 | workspaceRoot string, |
| 770 | submittedAt time.Time, |
| 771 | ) ([]memcontract.Candidate, error) { |
| 772 | scanner := bufio.NewScanner(strings.NewReader(output)) |
| 773 | scanner.Buffer(make([]byte, 0, 64*1024), 1024*1024) |
| 774 | candidates := make([]memcontract.Candidate, 0) |
| 775 | lineNumber := 0 |
| 776 | for scanner.Scan() { |
| 777 | lineNumber++ |
| 778 | raw := normalizeExtractorJSONLLine(scanner.Text()) |
| 779 | if raw == "" { |
| 780 | continue |
| 781 | } |
| 782 | var line extractedMemoryLine |
| 783 | if err := json.Unmarshal([]byte(raw), &line); err != nil { |
| 784 | return nil, fmt.Errorf("daemon: decode memory extractor line %d: %w", lineNumber, err) |
| 785 | } |
| 786 | candidate, err := candidateFromExtractedLine(line, turn, workspaceRoot, submittedAt) |
| 787 | if err != nil { |
| 788 | return nil, fmt.Errorf("daemon: normalize memory extractor line %d: %w", lineNumber, err) |
| 789 | } |
| 790 | candidates = append(candidates, candidate) |
| 791 | } |
| 792 | if err := scanner.Err(); err != nil { |
| 793 | return nil, fmt.Errorf("daemon: scan memory extractor output: %w", err) |
| 794 | } |
| 795 | return candidates, nil |
| 796 | } |
| 797 | |
| 798 | func normalizeExtractorJSONLLine(raw string) string { |
| 799 | line := strings.TrimSpace(raw) |