Add evidence context policy preparation
This commit is contained in:
74
internal/modules/dnd/register/evidence.go
Normal file
74
internal/modules/dnd/register/evidence.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package register
|
||||
|
||||
import (
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/core/source"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
|
||||
)
|
||||
|
||||
func registerEvidence(registry *pipeline.ArtifactEvidenceRegistry) error {
|
||||
return runRegistrations([]registration{
|
||||
{name: "spells evidence", register: func() error { return pipeline.RegisterArtifactEvidence(registry, dnd.SpellListKind, spellEvidence) }},
|
||||
{name: "npcs evidence", register: func() error { return pipeline.RegisterArtifactEvidence(registry, dnd.NPCListKind, npcEvidence) }},
|
||||
{name: "combat turns evidence", register: func() error {
|
||||
return pipeline.RegisterArtifactEvidence(registry, dnd.CombatTurnListKind, combatTurnEvidence)
|
||||
}},
|
||||
{name: "item events evidence", register: func() error {
|
||||
return pipeline.RegisterArtifactEvidence(registry, dnd.ItemEventListKind, itemEventEvidence)
|
||||
}},
|
||||
{name: "npc interactions evidence", register: func() error {
|
||||
return pipeline.RegisterArtifactEvidence(registry, dnd.NPCInteractionListKind, npcInteractionEvidence)
|
||||
}},
|
||||
{name: "scene descriptions evidence", register: func() error {
|
||||
return pipeline.RegisterArtifactEvidence(registry, dnd.SceneDescriptionListKind, sceneDescriptionEvidence)
|
||||
}},
|
||||
})
|
||||
}
|
||||
|
||||
func spellEvidence(value dnd.SpellList) []source.SourceRef {
|
||||
var refs []source.SourceRef
|
||||
for _, record := range value.SpellCasts {
|
||||
refs = append(refs, record.SourceRefs...)
|
||||
}
|
||||
return append([]source.SourceRef(nil), refs...)
|
||||
}
|
||||
|
||||
func npcEvidence(value dnd.NPCList) []source.SourceRef {
|
||||
var refs []source.SourceRef
|
||||
for _, record := range value.NPCs {
|
||||
refs = append(refs, record.SourceRefs...)
|
||||
}
|
||||
return append([]source.SourceRef(nil), refs...)
|
||||
}
|
||||
|
||||
func combatTurnEvidence(value dnd.CombatTurnList) []source.SourceRef {
|
||||
var refs []source.SourceRef
|
||||
for _, record := range value.CombatTurns {
|
||||
refs = append(refs, record.SourceRefs...)
|
||||
}
|
||||
return append([]source.SourceRef(nil), refs...)
|
||||
}
|
||||
|
||||
func itemEventEvidence(value dnd.ItemEventList) []source.SourceRef {
|
||||
var refs []source.SourceRef
|
||||
for _, record := range value.Events {
|
||||
refs = append(refs, record.SourceRefs...)
|
||||
}
|
||||
return append([]source.SourceRef(nil), refs...)
|
||||
}
|
||||
|
||||
func npcInteractionEvidence(value dnd.NPCInteractionList) []source.SourceRef {
|
||||
var refs []source.SourceRef
|
||||
for _, record := range value.Interactions {
|
||||
refs = append(refs, record.SourceRefs...)
|
||||
}
|
||||
return append([]source.SourceRef(nil), refs...)
|
||||
}
|
||||
|
||||
func sceneDescriptionEvidence(value dnd.SceneDescriptionList) []source.SourceRef {
|
||||
refs := make([]source.SourceRef, 0, len(value.Scenes))
|
||||
for _, record := range value.Scenes {
|
||||
refs = append(refs, record.SourceRef)
|
||||
}
|
||||
return refs
|
||||
}
|
||||
@@ -21,6 +21,9 @@ func Register(registries pipeline.Registries, assets *llm.AssetRegistry) error {
|
||||
if err := registerModules(registries); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := registerEvidence(registries.ArtifactEvidence); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := registerValidators(registries); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -45,6 +48,8 @@ func validateRegistries(registries pipeline.Registries, assets *llm.AssetRegistr
|
||||
return fmt.Errorf("dnd registrar: chunker registry must not be nil")
|
||||
case registries.ArtifactCodecs == nil:
|
||||
return fmt.Errorf("dnd registrar: artifact codec registry must not be nil")
|
||||
case registries.ArtifactEvidence == nil:
|
||||
return fmt.Errorf("dnd registrar: artifact evidence registry must not be nil")
|
||||
case registries.Extractors == nil:
|
||||
return fmt.Errorf("dnd registrar: extractor registry must not be nil")
|
||||
case registries.Mergers == nil:
|
||||
|
||||
@@ -50,6 +50,7 @@ func TestRegisterAddsDNDFamily(t *testing.T) {
|
||||
assertContainsKeys(t, "extractors", registries.Extractors.RegisteredKeys(), []string{"dnd/spells", npcextract.Key, combatextract.Key, itemeventextract.Key, interactionextract.Key, scenedescriptionextract.Key})
|
||||
assertContainsKeys(t, "normalizers", registries.Normalizers.RegisteredKeys(), []string{spellnormalize.Key, npcnormalize.Key, combatnormalize.Key, itemeventnormalize.Key, interactionnormalize.Key, scenedescriptionnormalize.Key, pipeline.DefaultNormalizeModule})
|
||||
assertContainsArtifactKinds(t, registries.ArtifactCodecs.RegisteredKinds(), []contracts.ArtifactKind{dnd.SpellListKind, dnd.NPCListKind, dnd.CombatTurnListKind, dnd.ItemEventListKind, dnd.NPCInteractionListKind, dnd.SceneDescriptionListKind})
|
||||
assertContainsArtifactKinds(t, registries.ArtifactEvidence.RegisteredKinds(), []contracts.ArtifactKind{dnd.SpellListKind, dnd.NPCListKind, dnd.CombatTurnListKind, dnd.ItemEventListKind, dnd.NPCInteractionListKind, dnd.SceneDescriptionListKind})
|
||||
assertContainsArtifactKinds(t, registries.Mergers.RegisteredArtifactKinds(pipeline.DefaultMergeModule), []contracts.ArtifactKind{dnd.SpellListKind, dnd.NPCListKind, dnd.CombatTurnListKind, dnd.ItemEventListKind, dnd.NPCInteractionListKind, dnd.SceneDescriptionListKind})
|
||||
assertContainsArtifactKinds(t, registries.Normalizers.RegisteredArtifactKinds(pipeline.DefaultNormalizeModule), []contracts.ArtifactKind{dnd.SpellListKind, dnd.NPCListKind, dnd.CombatTurnListKind, dnd.ItemEventListKind, dnd.NPCInteractionListKind, dnd.SceneDescriptionListKind})
|
||||
assertContainsArtifactKinds(t, registries.Normalizers.RegisteredArtifactKinds(npcnormalize.Key), []contracts.ArtifactKind{dnd.NPCListKind})
|
||||
@@ -318,6 +319,46 @@ func TestRegisterAddsDNDFamily(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestEvidenceProjectorsPreserveDirectReferencesWithIndependentStorage(t *testing.T) {
|
||||
first := source.SourceRef{SourceID: "session", StartUnitID: 1, EndUnitID: 1}
|
||||
second := source.SourceRef{SourceID: "session", StartUnitID: 2, EndUnitID: 2}
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
project func() []source.SourceRef
|
||||
want []source.SourceRef
|
||||
}{
|
||||
{name: "spells", project: func() []source.SourceRef {
|
||||
return spellEvidence(dnd.SpellList{SpellCasts: []dnd.SpellCast{{SourceRefs: []source.SourceRef{first, second}}}})
|
||||
}, want: []source.SourceRef{first, second}},
|
||||
{name: "npcs", project: func() []source.SourceRef {
|
||||
return npcEvidence(dnd.NPCList{NPCs: []dnd.NPC{{SourceRefs: []source.SourceRef{first, second}}}})
|
||||
}, want: []source.SourceRef{first, second}},
|
||||
{name: "combat turns", project: func() []source.SourceRef {
|
||||
return combatTurnEvidence(dnd.CombatTurnList{CombatTurns: []dnd.CombatTurn{{SourceRefs: []source.SourceRef{first, second}}}})
|
||||
}, want: []source.SourceRef{first, second}},
|
||||
{name: "item events", project: func() []source.SourceRef {
|
||||
return itemEventEvidence(dnd.ItemEventList{Events: []dnd.ItemEvent{{SourceRefs: []source.SourceRef{first, second}}}})
|
||||
}, want: []source.SourceRef{first, second}},
|
||||
{name: "npc interactions", project: func() []source.SourceRef {
|
||||
return npcInteractionEvidence(dnd.NPCInteractionList{Interactions: []dnd.NPCInteraction{{SourceRefs: []source.SourceRef{first, second}}}})
|
||||
}, want: []source.SourceRef{first, second}},
|
||||
{name: "scene descriptions", project: func() []source.SourceRef {
|
||||
return sceneDescriptionEvidence(dnd.SceneDescriptionList{Scenes: []dnd.SceneDescription{{SourceRef: first}, {SourceRef: second}}})
|
||||
}, want: []source.SourceRef{first, second}},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
got := test.project()
|
||||
if !reflect.DeepEqual(got, test.want) {
|
||||
t.Fatalf("projected references = %#v, want %#v", got, test.want)
|
||||
}
|
||||
got[0].StartUnitID = 99
|
||||
if first.StartUnitID != 1 {
|
||||
t.Fatal("projector returned aliased reference storage")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func referenceSlot(slots []contracts.ReferenceSlot, name string) contracts.ReferenceSlot {
|
||||
for _, slot := range slots {
|
||||
if slot.Name == name {
|
||||
@@ -531,6 +572,7 @@ func TestRegisterRejectsMissingDNDDependenciesBeforeMutation(t *testing.T) {
|
||||
}{
|
||||
{name: "chunkers", remove: func(r *pipeline.Registries, _ **llm.AssetRegistry) { r.Chunkers = nil }, wantErr: "chunker registry"},
|
||||
{name: "artifact codecs", remove: func(r *pipeline.Registries, _ **llm.AssetRegistry) { r.ArtifactCodecs = nil }, wantErr: "artifact codec registry"},
|
||||
{name: "artifact evidence", remove: func(r *pipeline.Registries, _ **llm.AssetRegistry) { r.ArtifactEvidence = nil }, wantErr: "artifact evidence registry"},
|
||||
{name: "extractors", remove: func(r *pipeline.Registries, _ **llm.AssetRegistry) { r.Extractors = nil }, wantErr: "extractor registry"},
|
||||
{name: "mergers", remove: func(r *pipeline.Registries, _ **llm.AssetRegistry) { r.Mergers = nil }, wantErr: "merger registry"},
|
||||
{name: "normalizers", remove: func(r *pipeline.Registries, _ **llm.AssetRegistry) { r.Normalizers = nil }, wantErr: "normalizer registry"},
|
||||
@@ -568,15 +610,16 @@ func TestRegisterReportsDuplicateDNDRegistration(t *testing.T) {
|
||||
|
||||
func completeRegistries() pipeline.Registries {
|
||||
return pipeline.Registries{
|
||||
Inputs: pipeline.NewInputAdapterRegistry(),
|
||||
Chunkers: pipeline.NewChunkerRegistry(),
|
||||
ArtifactCodecs: pipeline.NewArtifactCodecRegistry(),
|
||||
Extractors: pipeline.NewExtractorRegistry(),
|
||||
Mergers: pipeline.NewMergerRegistry(),
|
||||
Normalizers: pipeline.NewNormalizerRegistry(),
|
||||
Validators: pipeline.NewValidatorRegistry(),
|
||||
ValidatorChains: pipeline.NewValidatorChainRegistry(),
|
||||
Outputs: pipeline.NewOutputEncoderRegistry(),
|
||||
Inputs: pipeline.NewInputAdapterRegistry(),
|
||||
Chunkers: pipeline.NewChunkerRegistry(),
|
||||
ArtifactCodecs: pipeline.NewArtifactCodecRegistry(),
|
||||
ArtifactEvidence: pipeline.NewArtifactEvidenceRegistry(),
|
||||
Extractors: pipeline.NewExtractorRegistry(),
|
||||
Mergers: pipeline.NewMergerRegistry(),
|
||||
Normalizers: pipeline.NewNormalizerRegistry(),
|
||||
Validators: pipeline.NewValidatorRegistry(),
|
||||
ValidatorChains: pipeline.NewValidatorChainRegistry(),
|
||||
Outputs: pipeline.NewOutputEncoderRegistry(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user