Attribute filtered revisions to their repair attempts

This commit is contained in:
2026-11-11 12:24:32 +00:00
parent d3a9edb29d
commit bcce4729e1
4 changed files with 63 additions and 10 deletions

View File

@@ -34,11 +34,12 @@ type repairWireRequest struct {
} `json:"response_format"`
}
type correctionProvider struct {
mu sync.Mutex
requests []repairWireRequest
attempts map[int]int
entered chan struct{}
wait bool
mu sync.Mutex
requests []repairWireRequest
attempts map[int]int
entered chan struct{}
wait bool
invalidFirstRevision bool
}
func (p *correctionProvider) ServeHTTP(w http.ResponseWriter, r *http.Request) {
@@ -92,6 +93,7 @@ func (p *correctionProvider) ServeHTTP(w http.ResponseWriter, r *http.Request) {
p.mu.Lock()
p.attempts[ref]++
attempt := p.attempts[ref]
invalid := p.invalidFirstRevision && attempt == 1
p.mu.Unlock()
if ref == 3 {
http.Error(w, `{"error":{"message":"context too long"}}`, http.StatusBadRequest)
@@ -101,12 +103,50 @@ func (p *correctionProvider) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if attempt > 1 {
confidence = 0.99
}
content = fmt.Sprintf(`{"proposal_ref":2,"action":"revise","correction":{"id":2,"original_text":"second","corrected_text":"Second","confidence":%v}}`, confidence)
id := 2
if invalid {
id, confidence = 99, 0.99
}
content = fmt.Sprintf(`{"proposal_ref":2,"action":"revise","correction":{"id":%d,"original_text":"second","corrected_text":"Second","confidence":%v}}`, id, confidence)
}
raw, _ := json.Marshal(content)
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, `{"model":"fixture","choices":[{"message":{"content":%s}}]}`, raw)
}
func TestSubprocessReportsDefectOnOriginatingRepair(t *testing.T) {
for _, tc := range []struct {
budget int
outcome string
recoveries int
}{{1, "exhausted", 1}, {2, "applied", 2}} {
t.Run(tc.outcome, func(t *testing.T) {
f, provider := setupCorrectionFixture(t, tc.budget, false, false)
provider.mu.Lock()
provider.invalidFirstRevision = true
provider.mu.Unlock()
if code, _, stderr := f.run(t, true); code != 0 {
t.Fatalf("code=%d stderr=%s", code, stderr)
}
doc := f.recoveries(t)
if *doc.Summary.ProposalResponses != 1 || *doc.Summary.ProposalResponsesWithFiltering != 0 || len(doc.Recoveries) != tc.recoveries {
t.Fatalf("unexpected recoveries: %+v", doc)
}
first := doc.Recoveries[0]
want := []reporting.FilteredProposal{{ProposalIndex: 1, Reason: "invalid_target_segment_id", Count: 1}}
if first.Operation != "correction_repair" || !reflect.DeepEqual(first.FilteredProposals, want) || !reflect.DeepEqual(first.Reasons, []string{"proposals_filtered"}) {
t.Fatalf("first repair recovery: %+v", first)
}
if tc.recoveries == 2 && !reflect.DeepEqual(doc.Recoveries[1].Reasons, []string{"correction_revised"}) {
t.Fatalf("successful repair recovery: %+v", doc.Recoveries[1])
}
report, err := os.ReadFile(filepath.Join(f.dir, "report.md"))
if err != nil || !strings.Contains(string(report), fmt.Sprintf("| 1 | 1 | 1 | %d | %s |", tc.budget, tc.outcome)) {
t.Fatalf("repair outcome: %s %v", report, err)
}
})
}
}
func setupCorrectionFixture(t *testing.T, attempts int, replacement, wait bool) (processFixture, *correctionProvider) {
t.Helper()
f := newProcessFixture(t, "normal", "[grammar]")