Define correction repair response and conversation replay
This commit is contained in:
31
internal/framework/proposal_generation/repair.go
Normal file
31
internal/framework/proposal_generation/repair.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package proposal_generation
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"gitea.maximumdirect.net/eric/audita/v3/internal/framework/outcomes"
|
||||
"gitea.maximumdirect.net/eric/audita/v3/internal/framework/structuredoutput"
|
||||
)
|
||||
|
||||
// RepairResponse is one model response for an original proposal reference.
|
||||
type RepairResponse struct {
|
||||
ProposalRef int `json:"proposal_ref"`
|
||||
Action string `json:"action"`
|
||||
Correction *StructuredCorrectionProposal `json:"correction"`
|
||||
}
|
||||
|
||||
// DecodeRepairResponse checks correspondence after structural schema validation.
|
||||
func DecodeRepairResponse(content []byte, expectedRef int) (RepairResponse, error) {
|
||||
var response RepairResponse
|
||||
if err := json.Unmarshal(content, &response); err != nil {
|
||||
return RepairResponse{}, invalidRepairResponse(err)
|
||||
}
|
||||
if response.ProposalRef != expectedRef || (response.Action != "revise" || response.Correction == nil) && (response.Action != "withdraw" || response.Correction != nil) {
|
||||
return RepairResponse{}, invalidRepairResponse(nil)
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func invalidRepairResponse(cause error) error {
|
||||
return &structuredoutput.Failure{Class: structuredoutput.FailureRecoverable, Reason: outcomes.ReasonInvalidOutput, Message: "correction repair response is unusable", Cause: cause}
|
||||
}
|
||||
35
internal/framework/proposal_generation/repair_test.go
Normal file
35
internal/framework/proposal_generation/repair_test.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package proposal_generation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"gitea.maximumdirect.net/eric/audita/v3/internal/framework/outcomes"
|
||||
"gitea.maximumdirect.net/eric/audita/v3/internal/framework/structuredoutput"
|
||||
)
|
||||
|
||||
func TestDecodeRepairResponse(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name, content string
|
||||
valid bool
|
||||
}{
|
||||
{"revision with deletion", `{"proposal_ref":2,"action":"revise","correction":{"id":1,"original_text":" ","corrected_text":"","confidence":0.5}}`, true},
|
||||
{"withdrawal", `{"proposal_ref":2,"action":"withdraw","correction":null}`, true},
|
||||
{"wrong reference", `{"proposal_ref":1,"action":"withdraw","correction":null}`, false},
|
||||
{"missing revision", `{"proposal_ref":2,"action":"revise","correction":null}`, false},
|
||||
{"withdrawal with revision", `{"proposal_ref":2,"action":"withdraw","correction":{"id":1}}`, false},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
_, err := DecodeRepairResponse([]byte(tc.content), 2)
|
||||
if tc.valid && err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !tc.valid {
|
||||
var failure *structuredoutput.Failure
|
||||
if !errors.As(err, &failure) || failure.Reason != outcomes.ReasonInvalidOutput || failure.Class != structuredoutput.FailureRecoverable {
|
||||
t.Fatalf("failure = %v", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user