Accept span deletions in structured responses

This commit is contained in:
2026-09-25 02:50:46 +00:00
parent 640f663ace
commit 93f62c9095
12 changed files with 115 additions and 16 deletions

View File

@@ -185,6 +185,59 @@ func TestPreparedAdapterRepairsAndClassifies(t *testing.T) {
}
}
func TestCorrectionSchemaReplacementValuesThroughAdapter(t *testing.T) {
for _, tc := range []struct {
name, original, replacement string
valid bool
repairs int
}{
{name: "empty replacement", original: "uh ", replacement: `"corrected_text":""`, valid: true, repairs: 2},
{name: "spaces replacement", original: "hello", replacement: `"corrected_text":" "`, valid: true, repairs: 2},
{name: "ordinary replacement", original: " ", replacement: `"corrected_text":" "`, valid: true, repairs: 2},
{name: "missing replacement", original: "uh ", replacement: "", valid: false},
{name: "null replacement", original: "uh ", replacement: `"corrected_text":null`, valid: false},
{name: "numeric replacement", original: "uh ", replacement: `"corrected_text":1`, valid: false},
{name: "empty original", original: "", replacement: `"corrected_text":"x"`, valid: false},
} {
t.Run(tc.name, func(t *testing.T) {
fields := []string{`"id":1`, `"original_text":` + fmt.Sprintf("%q", tc.original), `"confidence":0.9`}
if tc.replacement != "" {
fields = append(fields, tc.replacement)
}
payload := `{"corrections":[{` + strings.Join(fields, ",") + `}]}`
runtime, count, _ := adapterFixture(t, []reply{{200, payload}}, 0, tc.repairs, nil)
client, err := runtime.NewRoleClient("proposal", CallHooks{})
if err != nil {
t.Fatal(err)
}
var out map[string]any
response, err := client.CompleteStructured(context.Background(), adapterRequest(responseschema.CorrectionSetKey), &out)
if got := count.Load(); got != 1 {
t.Fatalf("expected one provider generation, got %d", got)
}
if response.Execution.StructuralRepairs != 0 || response.Execution.ProviderAttempts != 1 {
t.Fatalf("unexpected repair/generation counts: %+v", response.Execution)
}
if tc.valid {
if err != nil {
t.Fatal(err)
}
corrections := out["corrections"].([]any)
item := corrections[0].(map[string]any)
var expected string
if err := json.Unmarshal([]byte(strings.TrimPrefix(tc.replacement, `"corrected_text":`)), &expected); err != nil {
t.Fatal(err)
}
if item["corrected_text"] != expected || item["original_text"] != tc.original {
t.Fatalf("span values changed: %+v", item)
}
} else if !structuredoutput.IsMalformedError(err) {
t.Fatalf("expected structural rejection, got %v", err)
}
})
}
}
func TestPreparedAdapterMetadataAndTargetGuard(t *testing.T) {
requestSeen := false
var posted struct {