Redact NPC normalization context errors
This commit is contained in:
@@ -119,15 +119,15 @@ func buildNormalizeContextMaterials(doc *source.SourceDocument, records []dnd.NP
|
|||||||
|
|
||||||
windows, err := normalizeContextWindows(doc.Units, coalesceIntervals(intervals), cited)
|
windows, err := normalizeContextWindows(doc.Units, coalesceIntervals(intervals), cited)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return normalizeContextMaterials{}, false, fmt.Errorf("build NPC normalization context: copy source metadata: %w", err)
|
return normalizeContextMaterials{}, false, fmt.Errorf("build NPC normalization context: invalid source metadata")
|
||||||
}
|
}
|
||||||
candidateContent, err := json.Marshal(normalizeCandidateInput{NPCs: candidates})
|
candidateContent, err := json.Marshal(normalizeCandidateInput{NPCs: candidates})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return normalizeContextMaterials{}, false, fmt.Errorf("build NPC normalization context: encode candidates: %w", err)
|
return normalizeContextMaterials{}, false, fmt.Errorf("build NPC normalization context: invalid candidate material")
|
||||||
}
|
}
|
||||||
transcriptContent, err := json.Marshal(normalizeTranscriptInput{Windows: windows})
|
transcriptContent, err := json.Marshal(normalizeTranscriptInput{Windows: windows})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return normalizeContextMaterials{}, false, fmt.Errorf("build NPC normalization context: encode transcript: %w", err)
|
return normalizeContextMaterials{}, false, fmt.Errorf("build NPC normalization context: invalid transcript material")
|
||||||
}
|
}
|
||||||
return normalizeContextMaterials{
|
return normalizeContextMaterials{
|
||||||
Candidates: newNormalizeInputMaterial("candidates", candidateContent),
|
Candidates: newNormalizeInputMaterial("candidates", candidateContent),
|
||||||
|
|||||||
@@ -136,17 +136,39 @@ func TestNormalizeInvalidStructuredOutputAndOperationalErrorsRemainDistinct(t *t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNormalizeRejectsContextEncodingFailuresWithoutLeakingContent(t *testing.T) {
|
func TestNormalizeRedactsContextMaterialFailures(t *testing.T) {
|
||||||
client := &recordingNPCNormalizerClient{}
|
client := &recordingNPCNormalizerClient{}
|
||||||
normalizer := newNormalizer(t, client)
|
normalizer := newNormalizer(t, client)
|
||||||
doc := semanticDocument()
|
const (
|
||||||
doc.Units[0].Metadata = map[string]any{"invalid": math.NaN()}
|
metadataKey = "normalizer-sensitive-metadata-key"
|
||||||
input := dnd.NPCList{NPCs: []dnd.NPC{
|
metadataValue = "normalizer-sensitive-metadata-value"
|
||||||
{Name: "Mira", SourceRefs: []source.SourceRef{{SourceID: doc.ID, StartUnitID: 10, EndUnitID: 10}}},
|
sourceID = "normalizer-sensitive-source-id"
|
||||||
{Name: "Mira Thorn", SourceRefs: []source.SourceRef{{SourceID: doc.ID, StartUnitID: 20, EndUnitID: 20}}},
|
originPath = "file:///normalizer-sensitive-origin.json"
|
||||||
|
transcript = "normalizer-sensitive-transcript"
|
||||||
|
firstName = "Normalizer Sensitive"
|
||||||
|
secondName = "Normalizer Sensitive Alias"
|
||||||
|
)
|
||||||
|
doc := &source.SourceDocument{ID: sourceID, Units: []source.SourceUnit{
|
||||||
|
{ID: 10, Kind: "speech", Text: transcript, Metadata: map[string]any{metadataKey: math.NaN(), "value": metadataValue}},
|
||||||
|
{ID: 20, Kind: "speech", Text: "other context"},
|
||||||
}}
|
}}
|
||||||
if _, err := normalizer.Normalize(context.Background(), normalizeRequestWithSource(input, doc)); err == nil || !strings.Contains(err.Error(), "build semantic context") || strings.Contains(err.Error(), doc.Units[0].Text) || len(client.requests) != 0 {
|
input := dnd.NPCList{NPCs: []dnd.NPC{
|
||||||
t.Fatalf("Normalize() error = %v, calls = %d; want safe preparation error before completion", err, len(client.requests))
|
{Name: firstName, SourceRefs: []source.SourceRef{{SourceID: doc.ID, StartUnitID: 10, EndUnitID: 10}}},
|
||||||
|
{Name: secondName, SourceRefs: []source.SourceRef{{SourceID: doc.ID, StartUnitID: 20, EndUnitID: 20}}},
|
||||||
|
}}
|
||||||
|
request := normalizeRequestWithSource(input, doc)
|
||||||
|
request.SourceInput = contracts.NewLLMInputMaterial("source", "application/json", []byte(transcript), "sha256:test", originPath)
|
||||||
|
_, err := normalizer.Normalize(context.Background(), request)
|
||||||
|
if err == nil || !strings.Contains(err.Error(), "build NPC normalization context: invalid source metadata") {
|
||||||
|
t.Fatalf("Normalize() error = %v; want content-safe context-material failure", err)
|
||||||
|
}
|
||||||
|
for _, forbidden := range []string{metadataKey, metadataValue, transcript, firstName, secondName, sourceID, originPath, "float64", "non-finite"} {
|
||||||
|
if strings.Contains(err.Error(), forbidden) {
|
||||||
|
t.Fatalf("Normalize() error leaked %q: %v", forbidden, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(client.requests) != 0 {
|
||||||
|
t.Fatalf("completion calls = %d, want context failure before completion", len(client.requests))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user