Implement NPC extraction follow-up fixes
This commit is contained in:
@@ -17,8 +17,8 @@ func canonicalizeResponse(response *extractionResponse, doc *source.SourceDocume
|
||||
canonicalizeNPC(&response.NPCs[index])
|
||||
}
|
||||
sort.SliceStable(response.NPCs, func(i, j int) bool {
|
||||
left, leftOK := earliestSourceUnit(doc, response.NPCs[i])
|
||||
right, rightOK := earliestSourceUnit(doc, response.NPCs[j])
|
||||
left, leftOK := earliestSourceIndex(doc, response.NPCs[i])
|
||||
right, rightOK := earliestSourceIndex(doc, response.NPCs[j])
|
||||
if leftOK != rightOK {
|
||||
return leftOK
|
||||
}
|
||||
@@ -77,7 +77,9 @@ func sameSourceRef(left npcSourceRefResponse, right npcSourceRefResponse) bool {
|
||||
left.EndUnitID.Int() == right.EndUnitID.Int()
|
||||
}
|
||||
|
||||
func earliestSourceUnit(doc *source.SourceDocument, npc npcResponse) (int, bool) {
|
||||
func earliestSourceIndex(doc *source.SourceDocument, npc npcResponse) (int, bool) {
|
||||
earliest := 0
|
||||
found := false
|
||||
for _, ref := range npc.SourceRefs {
|
||||
start := ref.StartUnitID.Int()
|
||||
end := ref.EndUnitID.Int()
|
||||
@@ -87,10 +89,13 @@ func earliestSourceUnit(doc *source.SourceDocument, npc npcResponse) (int, bool)
|
||||
if !startOK || !endOK || startIndex > endIndex {
|
||||
continue
|
||||
}
|
||||
return start, true
|
||||
if !found || startIndex < earliest {
|
||||
earliest = startIndex
|
||||
found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0, false
|
||||
return earliest, found
|
||||
}
|
||||
|
||||
func unitSortValue(ref shared.UnitRef) int {
|
||||
|
||||
@@ -56,6 +56,38 @@ func TestExtractReturnsCanonicalNPCListFromPrivateResponse(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractOrdersNPCsBySourcePositionRatherThanUnitID(t *testing.T) {
|
||||
client := &fakeNPCsLLMClient{response: extractionResponse{NPCs: []npcResponse{
|
||||
{
|
||||
Name: "Later NPC", Aliases: []string{}, Description: "Appears later.", Relationships: []npcRelationshipResponse{},
|
||||
SourceRefs: responseSourceRefs(10, 10),
|
||||
},
|
||||
{
|
||||
Name: "Earlier NPC", Aliases: []string{}, Description: "Appears first.", Relationships: []npcRelationshipResponse{},
|
||||
SourceRefs: []npcSourceRefResponse{
|
||||
{StartUnitID: sharedUnitRef(50), EndUnitID: sharedUnitRef(50)},
|
||||
{StartUnitID: sharedUnitRef(100), EndUnitID: sharedUnitRef(100)},
|
||||
},
|
||||
},
|
||||
}}}
|
||||
req := extractionRequest()
|
||||
req.Source.Units = []source.SourceUnit{
|
||||
{ID: 100, Kind: "transcript_segment", Text: "Earlier NPC appears."},
|
||||
{ID: 10, Kind: "transcript_segment", Text: "Later NPC appears."},
|
||||
{ID: 50, Kind: "transcript_segment", Text: "Earlier NPC appears again."},
|
||||
}
|
||||
req.Chunk.Units = append([]source.SourceUnit(nil), req.Source.Units...)
|
||||
req.Chunk.Ref = source.SourceRef{SourceID: req.Source.ID, StartUnitID: 100, EndUnitID: 50}
|
||||
|
||||
result, err := newExtractor(t, client).Extract(context.Background(), req)
|
||||
if err != nil {
|
||||
t.Fatalf("Extract() error = %v, want nil", err)
|
||||
}
|
||||
if len(result.Value.NPCs) != 2 || result.Value.NPCs[0].Name != "Earlier NPC" || result.Value.NPCs[1].Name != "Later NPC" {
|
||||
t.Fatalf("NPC order = %#v, want source-document order", result.Value.NPCs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractPassesCampaignReferencesAsPromptInputs(t *testing.T) {
|
||||
client := &fakeNPCsLLMClient{response: extractionResponse{NPCs: []npcResponse{}}}
|
||||
req := extractionRequest()
|
||||
|
||||
Reference in New Issue
Block a user