Add evidence context policy preparation

This commit is contained in:
2026-07-27 18:04:12 +00:00
parent 64d461fc18
commit 224a8292c4
21 changed files with 900 additions and 98 deletions

View 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
}

View File

@@ -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:

View File

@@ -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(),
}
}

View File

@@ -28,6 +28,7 @@ var _ contracts.OutputEncoder = (*Encoder)(nil)
type Options struct {
IncludeChunkMap bool
EvidenceContext pipeline.EvidenceContextPolicy
}
type Encoder struct {
@@ -39,6 +40,7 @@ func New() *Encoder {
}
func NewWithOptions(options Options) *Encoder {
options.EvidenceContext.LaneIDs = append([]string(nil), options.EvidenceContext.LaneIDs...)
return &Encoder{options: options}
}
@@ -46,6 +48,15 @@ func (e *Encoder) Key() string {
return Key
}
func (e *Encoder) EvidenceContextPolicy() pipeline.EvidenceContextPolicy {
if e == nil {
return pipeline.EvidenceContextPolicy{}
}
policy := e.options.EvidenceContext
policy.LaneIDs = append([]string(nil), policy.LaneIDs...)
return policy
}
func (e *Encoder) Encode(ctx context.Context, req contracts.OutputRequest) (contracts.OutputResult, error) {
if e == nil {
return contracts.OutputResult{}, encoderErrorf("encoder must not be nil")
@@ -74,7 +85,7 @@ func ModuleSpec() pipeline.ModuleSpec {
}
func Register(registry *pipeline.OutputEncoderRegistry) error {
return registry.RegisterBuilderWithSpec(ModuleSpec(), validateOptions, func(request pipeline.BuildRequest) (contracts.OutputEncoder, error) {
return registry.RegisterBuilderWithProfileValidation(ModuleSpec(), validateOptions, validateProfileOptions, func(request pipeline.BuildRequest) (contracts.OutputEncoder, error) {
options, err := DecodeOptions(request.Options)
if err != nil {
return nil, err
@@ -89,17 +100,126 @@ func validateOptions(options map[string]any) error {
}
func DecodeOptions(options map[string]any) (Options, error) {
if err := pipeline.RejectUnknownOptions(options, "include_chunk_map"); err != nil {
if err := pipeline.RejectUnknownOptions(options, "include_chunk_map", "evidence_context"); err != nil {
return Options{}, encoderErrorf("%w", err)
}
decoded := Options{}
if value, ok := options["include_chunk_map"]; ok {
enabled, ok := value.(bool)
if !ok {
return Options{}, encoderErrorf("option %q must be a boolean", "include_chunk_map")
}
return Options{IncludeChunkMap: enabled}, nil
decoded.IncludeChunkMap = enabled
}
return Options{}, nil
if value, ok := options["evidence_context"]; ok {
policy, err := decodeEvidenceContextPolicy(value)
if err != nil {
return Options{}, err
}
decoded.EvidenceContext = policy
}
return decoded, nil
}
func validateProfileOptions(context pipeline.OutputProfileOptionContext, options map[string]any) error {
decoded, err := DecodeOptions(options)
if err != nil || !decoded.EvidenceContext.Enabled {
return err
}
configured := make(map[string]struct{}, len(context.LaneIDs))
for _, laneID := range context.LaneIDs {
configured[laneID] = struct{}{}
}
for _, laneID := range decoded.EvidenceContext.LaneIDs {
if _, ok := configured[laneID]; !ok {
return encoderErrorf("evidence_context lane %q is not configured", laneID)
}
}
return nil
}
func decodeEvidenceContextPolicy(value any) (pipeline.EvidenceContextPolicy, error) {
object, ok := value.(map[string]any)
if !ok {
return pipeline.EvidenceContextPolicy{}, encoderErrorf("option %q must be an object", "evidence_context")
}
if err := pipeline.RejectUnknownOptions(object, "enabled", "lanes", "window_units"); err != nil {
return pipeline.EvidenceContextPolicy{}, encoderErrorf("evidence_context: %w", err)
}
enabledValue, ok := object["enabled"]
if !ok {
return pipeline.EvidenceContextPolicy{}, encoderErrorf("evidence_context option %q is required", "enabled")
}
enabled, ok := enabledValue.(bool)
if !ok {
return pipeline.EvidenceContextPolicy{}, encoderErrorf("evidence_context option %q must be a boolean", "enabled")
}
if !enabled {
if _, ok := object["lanes"]; ok {
return pipeline.EvidenceContextPolicy{}, encoderErrorf("evidence_context option %q is not allowed when disabled", "lanes")
}
if _, ok := object["window_units"]; ok {
return pipeline.EvidenceContextPolicy{}, encoderErrorf("evidence_context option %q is not allowed when disabled", "window_units")
}
return pipeline.EvidenceContextPolicy{}, nil
}
rawLanes, ok := object["lanes"]
if !ok {
return pipeline.EvidenceContextPolicy{}, encoderErrorf("evidence_context option %q is required when enabled", "lanes")
}
lanes, err := decodeEvidenceLaneIDs(rawLanes)
if err != nil {
return pipeline.EvidenceContextPolicy{}, err
}
windowUnits := 3
if rawWindow, ok := object["window_units"]; ok {
value, ok := rawWindow.(int)
if !ok {
return pipeline.EvidenceContextPolicy{}, encoderErrorf("evidence_context option %q must be an integer", "window_units")
}
if value < 0 {
return pipeline.EvidenceContextPolicy{}, encoderErrorf("evidence_context option %q must not be negative", "window_units")
}
windowUnits = value
}
return pipeline.EvidenceContextPolicy{Enabled: true, WindowUnits: windowUnits, LaneIDs: lanes}, nil
}
func decodeEvidenceLaneIDs(value any) ([]string, error) {
var raw []any
switch typed := value.(type) {
case []any:
raw = typed
case []string:
raw = make([]any, len(typed))
for i := range typed {
raw[i] = typed[i]
}
default:
return nil, encoderErrorf("evidence_context option %q must be an array", "lanes")
}
if len(raw) == 0 {
return nil, encoderErrorf("evidence_context option %q must not be empty", "lanes")
}
seen := make(map[string]struct{}, len(raw))
lanes := make([]string, 0, len(raw))
for _, value := range raw {
lane, ok := value.(string)
if !ok {
return nil, encoderErrorf("evidence_context lane values must be strings")
}
lane = strings.TrimSpace(lane)
if lane == "" {
return nil, encoderErrorf("evidence_context lane values must not be empty")
}
if _, ok := seen[lane]; ok {
return nil, encoderErrorf("evidence_context lane %q is duplicated", lane)
}
seen[lane] = struct{}{}
lanes = append(lanes, lane)
}
sort.Strings(lanes)
return lanes, nil
}
type indexFile struct {

View File

@@ -68,13 +68,62 @@ func TestDecodeOptions(t *testing.T) {
if err != nil {
t.Fatalf("DecodeOptions() error = %v, want nil", err)
}
if got != test.want {
if !reflect.DeepEqual(got, test.want) {
t.Fatalf("DecodeOptions() = %#v, want %#v", got, test.want)
}
})
}
}
func TestDecodeEvidenceContextOptions(t *testing.T) {
for _, test := range []struct {
name string
options map[string]any
want pipeline.EvidenceContextPolicy
wantErr string
}{
{name: "disabled", options: map[string]any{"evidence_context": map[string]any{"enabled": false}}},
{name: "enabled default window", options: map[string]any{"evidence_context": map[string]any{"enabled": true, "lanes": []any{"npcs"}}}, want: pipeline.EvidenceContextPolicy{Enabled: true, WindowUnits: 3, LaneIDs: []string{"npcs"}}},
{name: "explicit zero window and normalized lanes", options: map[string]any{"evidence_context": map[string]any{"enabled": true, "lanes": []any{" spells ", "npcs"}, "window_units": 0}}, want: pipeline.EvidenceContextPolicy{Enabled: true, WindowUnits: 0, LaneIDs: []string{"npcs", "spells"}}},
{name: "duplicate lanes", options: map[string]any{"evidence_context": map[string]any{"enabled": true, "lanes": []any{"npcs", " npcs "}}}, wantErr: "duplicated"},
{name: "unknown nested option", options: map[string]any{"evidence_context": map[string]any{"enabled": false, "extra": true}}, wantErr: "unknown option"},
{name: "disabled nested fields", options: map[string]any{"evidence_context": map[string]any{"enabled": false, "lanes": []any{"npcs"}}}, wantErr: "not allowed"},
{name: "invalid object", options: map[string]any{"evidence_context": true}, wantErr: "must be an object"},
{name: "invalid lane type", options: map[string]any{"evidence_context": map[string]any{"enabled": true, "lanes": "npcs"}}, wantErr: "must be an array"},
{name: "invalid window type", options: map[string]any{"evidence_context": map[string]any{"enabled": true, "lanes": []any{"npcs"}, "window_units": "3"}}, wantErr: "must be an integer"},
} {
t.Run(test.name, func(t *testing.T) {
got, err := DecodeOptions(test.options)
if test.wantErr != "" {
if err == nil || !strings.Contains(err.Error(), test.wantErr) {
t.Fatalf("DecodeOptions() error = %v, want %q", err, test.wantErr)
}
return
}
if err != nil {
t.Fatalf("DecodeOptions() error = %v, want nil", err)
}
if !reflect.DeepEqual(got.EvidenceContext, test.want) {
t.Fatalf("EvidenceContext = %#v, want %#v", got.EvidenceContext, test.want)
}
})
}
}
func TestProfileValidationRejectsUnknownEvidenceLaneAndCopiesInputs(t *testing.T) {
registry := pipeline.NewOutputEncoderRegistry()
if err := Register(registry); err != nil {
t.Fatal(err)
}
options := map[string]any{"evidence_context": map[string]any{"enabled": true, "lanes": []any{"npcs"}}}
if err := registry.ValidateProfileOptions(Key, pipeline.OutputProfileOptionContext{LaneIDs: []string{"npcs", "spells"}}, options); err != nil {
t.Fatalf("ValidateProfileOptions() error = %v, want nil", err)
}
if err := registry.ValidateProfileOptions(Key, pipeline.OutputProfileOptionContext{LaneIDs: []string{"spells"}}, options); err == nil || !strings.Contains(err.Error(), "not configured") {
t.Fatalf("ValidateProfileOptions() error = %v, want unknown lane failure", err)
}
}
func TestEncodeReturnsLogicalFilesForNormalizedOutputs(t *testing.T) {
req := contracts.OutputRequest{
Manifest: artifacts.RunManifest{RunID: "run-1", PipelineID: "pipeline-1"},

View File

@@ -153,7 +153,7 @@ func TestRunnerIndependentlyBoundsWorkersAndProviderCallsAcrossRegisteredModules
if err != nil {
t.Fatalf("Resolve() error = %v", err)
}
registries := pipeline.Registries{Inputs: catalog.Inputs, Chunkers: catalog.Chunkers, ArtifactCodecs: catalog.ArtifactCodecs, Extractors: catalog.Extractors, Mergers: catalog.Mergers, Normalizers: catalog.Normalizers, Validators: catalog.Validators, ValidatorChains: catalog.ValidatorChains, Outputs: catalog.Outputs}
registries := pipeline.Registries{Inputs: catalog.Inputs, Chunkers: catalog.Chunkers, ArtifactCodecs: catalog.ArtifactCodecs, ArtifactEvidence: catalog.ArtifactEvidence, Extractors: catalog.Extractors, Mergers: catalog.Mergers, Normalizers: catalog.Normalizers, Validators: catalog.Validators, ValidatorChains: catalog.ValidatorChains, Outputs: catalog.Outputs}
output, err := runPreparedPipeline(t, registries, resolved.ResolvedPipeline, client, pipeline.RunInput{RawInput: readDNDSpellsFixture(t), ExtractWorkers: 3})
if err != nil {
t.Fatalf("Run() error = %v", err)

View File

@@ -287,15 +287,16 @@ func (client *fakeNPCProductionLLMClient) requestCount(promptID string) int {
func productionNPCRegistries(t *testing.T) pipeline.Registries {
t.Helper()
registries := 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(),
}
assets := llm.NewAssetRegistry()
for _, registration := range []struct {
@@ -315,7 +316,7 @@ func productionNPCRegistries(t *testing.T) pipeline.Registries {
func moduleCatalog(registries pipeline.Registries) pipeline.ModuleCatalog {
return pipeline.ModuleCatalog{
Inputs: registries.Inputs, Chunkers: registries.Chunkers, ArtifactCodecs: registries.ArtifactCodecs,
Inputs: registries.Inputs, Chunkers: registries.Chunkers, ArtifactCodecs: registries.ArtifactCodecs, ArtifactEvidence: registries.ArtifactEvidence,
Extractors: registries.Extractors, Mergers: registries.Mergers, Normalizers: registries.Normalizers,
Validators: registries.Validators, ValidatorChains: registries.ValidatorChains, Outputs: registries.Outputs,
}

View File

@@ -88,6 +88,7 @@ func dndCapabilityCatalog(t *testing.T, inputSpec, extractorSpec pipeline.Module
}
codecs := pipeline.NewArtifactCodecRegistry()
evidence := pipeline.NewArtifactEvidenceRegistry()
if err := pipeline.RegisterArtifactCodec(codecs, spellcodec.New()); err != nil {
t.Fatalf("register capability codec: %v", err)
}
@@ -112,7 +113,7 @@ func dndCapabilityCatalog(t *testing.T, inputSpec, extractorSpec pipeline.Module
}
return pipeline.ModuleCatalog{
Inputs: inputs, Chunkers: chunkers, ArtifactCodecs: codecs, Extractors: extractors,
Inputs: inputs, Chunkers: chunkers, ArtifactCodecs: codecs, ArtifactEvidence: evidence, Extractors: extractors,
Mergers: mergers, Normalizers: normalizers, ValidatorChains: pipeline.NewValidatorChainRegistry(), Outputs: outputs,
}
}
@@ -148,6 +149,7 @@ func dndSpellsTestCatalog(t *testing.T, specs dndSpellsCatalogSpecs) pipeline.Mo
chunkers := pipeline.NewChunkerRegistry()
extractors := pipeline.NewExtractorRegistry()
codecs := pipeline.NewArtifactCodecRegistry()
evidence := pipeline.NewArtifactEvidenceRegistry()
mergers := pipeline.NewMergerRegistry()
normalizers := pipeline.NewNormalizerRegistry()
outputs := pipeline.NewOutputEncoderRegistry()
@@ -218,14 +220,15 @@ func dndSpellsTestCatalog(t *testing.T, specs dndSpellsCatalogSpecs) pipeline.Mo
}
return pipeline.ModuleCatalog{
Inputs: inputs,
Chunkers: chunkers,
ArtifactCodecs: codecs,
Extractors: extractors,
Mergers: mergers,
Normalizers: normalizers,
ValidatorChains: pipeline.NewValidatorChainRegistry(),
Outputs: outputs,
Inputs: inputs,
Chunkers: chunkers,
ArtifactCodecs: codecs,
ArtifactEvidence: evidence,
Extractors: extractors,
Mergers: mergers,
Normalizers: normalizers,
ValidatorChains: pipeline.NewValidatorChainRegistry(),
Outputs: outputs,
}
}

View File

@@ -284,13 +284,14 @@ func dndSpellsRunnerRegistries(t *testing.T) pipeline.Registries {
catalog := dndSpellsTestCatalog(t, dndSpellsCatalogSpecs{})
return pipeline.Registries{
Inputs: catalog.Inputs,
Chunkers: catalog.Chunkers,
ArtifactCodecs: catalog.ArtifactCodecs,
Extractors: catalog.Extractors,
Mergers: catalog.Mergers,
Normalizers: catalog.Normalizers,
Outputs: catalog.Outputs,
Inputs: catalog.Inputs,
Chunkers: catalog.Chunkers,
ArtifactCodecs: catalog.ArtifactCodecs,
ArtifactEvidence: catalog.ArtifactEvidence,
Extractors: catalog.Extractors,
Mergers: catalog.Mergers,
Normalizers: catalog.Normalizers,
Outputs: catalog.Outputs,
}
}