Simplify contextual entity grounding
This commit is contained in:
@@ -10,26 +10,34 @@ import (
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
||||
)
|
||||
|
||||
type orderedItemOccurrenceResponse struct {
|
||||
value itemOccurrenceResponse
|
||||
type orderedItemOccurrence struct {
|
||||
value dnd.ItemOccurrence
|
||||
earliest int
|
||||
hasEvidence bool
|
||||
}
|
||||
|
||||
func canonicalizeResponse(response *extractionResponse, order shared.SourceRefOrder, sourceID string, registry *itemregistry.Registry) error {
|
||||
if response == nil {
|
||||
return nil
|
||||
func canonicalItemOccurrenceList(response extractionResponse, order shared.SourceRefOrder, sourceID string, registry *itemregistry.Registry) (dnd.ItemOccurrenceList, error) {
|
||||
if response.Occurrences == nil {
|
||||
return dnd.ItemOccurrenceList{}, nil
|
||||
}
|
||||
ordered := make([]orderedItemOccurrenceResponse, len(response.Occurrences))
|
||||
for index := range response.Occurrences {
|
||||
canonical, found := registry.Lookup(response.Occurrences[index].Name)
|
||||
ordered := make([]orderedItemOccurrence, len(response.Occurrences))
|
||||
for index, occurrence := range response.Occurrences {
|
||||
item, found := registry.Lookup(occurrence.Name)
|
||||
if !found {
|
||||
return fmt.Errorf("occurrences[%d].name is not in the item registry", index)
|
||||
return dnd.ItemOccurrenceList{}, fmt.Errorf("occurrences[%d].name is not in the item registry", index)
|
||||
}
|
||||
response.Occurrences[index].Name = canonical.Name
|
||||
earliest, hasEvidence := canonicalizeItemOccurrence(&response.Occurrences[index], order, sourceID)
|
||||
ordered[index] = orderedItemOccurrenceResponse{
|
||||
value: response.Occurrences[index],
|
||||
refs := order.Canonicalize(itemOccurrenceSourceRefs(occurrence.SourceRefs, sourceID))
|
||||
earliest, hasEvidence := order.EarliestValid(refs)
|
||||
ordered[index] = orderedItemOccurrence{
|
||||
value: dnd.ItemOccurrence{
|
||||
ItemID: item.ID,
|
||||
Name: item.Name,
|
||||
Kind: dnd.ItemOccurrenceKind(occurrence.Kind),
|
||||
Quantity: cloneQuantity(occurrence.Quantity),
|
||||
From: occurrence.From,
|
||||
To: occurrence.To,
|
||||
SourceRefs: refs,
|
||||
},
|
||||
earliest: earliest,
|
||||
hasEvidence: hasEvidence,
|
||||
}
|
||||
@@ -43,40 +51,9 @@ func canonicalizeResponse(response *extractionResponse, order shared.SourceRefOr
|
||||
}
|
||||
return ordered[left].earliest < ordered[right].earliest
|
||||
})
|
||||
for index := range ordered {
|
||||
response.Occurrences[index] = ordered[index].value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func canonicalizeItemOccurrence(occurrence *itemOccurrenceResponse, order shared.SourceRefOrder, sourceID string) (int, bool) {
|
||||
if occurrence == nil {
|
||||
return 0, false
|
||||
}
|
||||
refs := order.Canonicalize(itemOccurrenceSourceRefs(occurrence.SourceRefs, sourceID))
|
||||
occurrence.SourceRefs = itemOccurrenceResponseRefs(refs)
|
||||
return order.EarliestValid(refs)
|
||||
}
|
||||
|
||||
func canonicalItemOccurrenceList(response extractionResponse, sourceID string, registry *itemregistry.Registry) (dnd.ItemOccurrenceList, error) {
|
||||
if response.Occurrences == nil {
|
||||
return dnd.ItemOccurrenceList{}, nil
|
||||
}
|
||||
occurrences := make([]dnd.ItemOccurrence, 0, len(response.Occurrences))
|
||||
for index, occurrence := range response.Occurrences {
|
||||
item, found := registry.Lookup(occurrence.Name)
|
||||
if !found {
|
||||
return dnd.ItemOccurrenceList{}, fmt.Errorf("occurrences[%d].name is not in the item registry", index)
|
||||
}
|
||||
occurrences = append(occurrences, dnd.ItemOccurrence{
|
||||
ItemID: item.ID,
|
||||
Name: item.Name,
|
||||
Kind: dnd.ItemOccurrenceKind(occurrence.Kind),
|
||||
Quantity: cloneQuantity(occurrence.Quantity),
|
||||
From: occurrence.From,
|
||||
To: occurrence.To,
|
||||
SourceRefs: itemOccurrenceSourceRefs(occurrence.SourceRefs, sourceID),
|
||||
})
|
||||
occurrences := make([]dnd.ItemOccurrence, len(ordered))
|
||||
for index, occurrence := range ordered {
|
||||
occurrences[index] = occurrence.value
|
||||
}
|
||||
return dnd.ItemOccurrenceList{Occurrences: occurrences}, nil
|
||||
}
|
||||
@@ -92,17 +69,6 @@ func itemOccurrenceSourceRefs(refs []itemOccurrenceSourceRefResponse, sourceID s
|
||||
return values
|
||||
}
|
||||
|
||||
func itemOccurrenceResponseRefs(refs []source.SourceRef) []itemOccurrenceSourceRefResponse {
|
||||
if refs == nil {
|
||||
return nil
|
||||
}
|
||||
values := make([]itemOccurrenceSourceRefResponse, len(refs))
|
||||
for index, ref := range refs {
|
||||
values[index] = itemOccurrenceSourceRefResponse{StartSegment: ref.StartUnitID, EndSegment: ref.EndUnitID}
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
func cloneQuantity(value *int) *int {
|
||||
if value == nil {
|
||||
return nil
|
||||
|
||||
@@ -161,12 +161,9 @@ func (e *Extractor) Extract(ctx context.Context, req contracts.TypedExtractionRe
|
||||
}, &response); err != nil {
|
||||
return contracts.TypedExtractionResult[dnd.ItemOccurrenceList]{}, extractorErrorf("complete structured output: %w", err)
|
||||
}
|
||||
if err := canonicalizeResponse(&response, order, req.Source.ID, registry); err != nil {
|
||||
return contracts.TypedExtractionResult[dnd.ItemOccurrenceList]{}, extractorErrorf("map item occurrence response: %w", err)
|
||||
}
|
||||
value, err := canonicalItemOccurrenceList(response, req.Source.ID, registry)
|
||||
value, err := canonicalItemOccurrenceList(response, order, req.Source.ID, registry)
|
||||
if err != nil {
|
||||
return contracts.TypedExtractionResult[dnd.ItemOccurrenceList]{}, extractorErrorf("resolve canonical item occurrence names: %w", err)
|
||||
return contracts.TypedExtractionResult[dnd.ItemOccurrenceList]{}, extractorErrorf("map item occurrence response: %w", err)
|
||||
}
|
||||
return contracts.TypedExtractionResult[dnd.ItemOccurrenceList]{Value: value}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user