Register D&D scene description pipeline
This commit is contained in:
111
internal/cli/dnd_scene_descriptions_contract_test.go
Normal file
111
internal/cli/dnd_scene_descriptions_contract_test.go
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"gitea.maximumdirect.net/eric/notarius/internal/core/config"
|
||||||
|
"gitea.maximumdirect.net/eric/notarius/internal/core/source"
|
||||||
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
|
||||||
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
|
||||||
|
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
|
||||||
|
scenecodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/scenedescriptions"
|
||||||
|
sceneextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/scenedescriptions"
|
||||||
|
scenenormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/scenedescriptions"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestProductionSceneDescriptionWorkflow(t *testing.T) {
|
||||||
|
components := productionTestComponents(t)
|
||||||
|
cfg := config.Default()
|
||||||
|
cfg.Pipelines["scene-descriptions"] = pipeline.PipelineProfile{
|
||||||
|
ID: "scene-descriptions",
|
||||||
|
Input: pipeline.Binding("seriatim"),
|
||||||
|
Chunk: pipeline.ModuleBinding{Module: "generic", Options: map[string]any{"max_units": 1}},
|
||||||
|
Output: pipeline.Binding("json"),
|
||||||
|
Artifacts: map[string]pipeline.ArtifactLaneProfile{
|
||||||
|
"scene-descriptions": {
|
||||||
|
Extract: pipeline.Binding(sceneextract.Key),
|
||||||
|
Normalize: pipeline.Binding(scenenormalize.Key),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
effective, err := cfg.Resolve(config.ResolveInput{PipelineID: "scene-descriptions", Catalog: catalogFromRegistries(components.registries)})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Resolve() error = %v", err)
|
||||||
|
}
|
||||||
|
lane := effective.ResolvedPipeline.Steps[0].ArtifactLanes[0]
|
||||||
|
if lane.ArtifactKind != dnd.SceneDescriptionListKind || lane.Extract.Module != sceneextract.Key || lane.Merge.Module != pipeline.DefaultMergeModule || lane.Normalize.Module != scenenormalize.Key {
|
||||||
|
t.Fatalf("resolved lane = %#v, want production scene-description composition", lane)
|
||||||
|
}
|
||||||
|
if len(lane.ExtractReferences.Bindings) != 0 || len(lane.NormalizeReferences.Bindings) != 0 {
|
||||||
|
t.Fatalf("resolved references = %#v / %#v, want no generated or required references", lane.ExtractReferences, lane.NormalizeReferences)
|
||||||
|
}
|
||||||
|
|
||||||
|
prepared, err := pipeline.Prepare(effective.ResolvedPipeline, components.registries, pipeline.ModuleDependencies{LLM: sceneDescriptionLLM{}})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Prepare() error = %v", err)
|
||||||
|
}
|
||||||
|
output, err := pipeline.New().Run(context.Background(), pipeline.RunInput{
|
||||||
|
Prepared: prepared,
|
||||||
|
RawInput: readRepositoryFile(t, "examples", "seriatim-minimal-transcript.json"),
|
||||||
|
ChunkCacheMode: pipeline.ChunkCacheBypass,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Run() error = %v", err)
|
||||||
|
}
|
||||||
|
if output.Manifest.ValidationStatus != "approved" || len(output.Rejected) != 0 || len(output.NormalizeOutputs) != 1 {
|
||||||
|
t.Fatalf("run output = %#v, want one approved normalized artifact", output)
|
||||||
|
}
|
||||||
|
normalizedOutput := output.NormalizeOutputs[0]
|
||||||
|
if normalizedOutput.NormalizerKey != scenenormalize.Key || normalizedOutput.Artifact.Kind != dnd.SceneDescriptionListKind || normalizedOutput.Artifact.Schema.ID != scenecodec.SchemaID || normalizedOutput.Artifact.Schema.Name != scenecodec.SchemaName || normalizedOutput.Artifact.Schema.Version != scenecodec.SchemaVersion {
|
||||||
|
t.Fatalf("normalized output = %#v, want registered durable scene-description schema", normalizedOutput)
|
||||||
|
}
|
||||||
|
|
||||||
|
var value dnd.SceneDescriptionList
|
||||||
|
if err := json.Unmarshal(normalizedOutput.Artifact.Content, &value); err != nil {
|
||||||
|
t.Fatalf("decode normalized artifact: %v", err)
|
||||||
|
}
|
||||||
|
want := dnd.SceneDescriptionList{Scenes: []dnd.SceneDescription{
|
||||||
|
{ID: "chunk-000001", SourceRef: source.SourceRef{SourceID: "session-alpha", StartUnitID: 1, EndUnitID: 1}, Kind: dnd.SceneKindNarrative, Title: "Aria casts Cure Wounds", Summary: "Aria casts Cure Wounds."},
|
||||||
|
{ID: "chunk-000002", SourceRef: source.SourceRef{SourceID: "session-alpha", StartUnitID: 2, EndUnitID: 2}, Kind: dnd.SceneKindCombat, Title: "Bandit mage casts Shield", Summary: "The bandit mage casts Shield."},
|
||||||
|
}}
|
||||||
|
if !reflect.DeepEqual(value, want) {
|
||||||
|
t.Fatalf("normalized scene descriptions = %#v, want %#v", value, want)
|
||||||
|
}
|
||||||
|
durable := decodeAssembledOutput[dnd.SceneDescriptionList](t, output.OutputFiles, "lanes/scene-descriptions.json")
|
||||||
|
if !reflect.DeepEqual(durable, want) {
|
||||||
|
t.Fatalf("durable output payload = %#v, want %#v", durable, want)
|
||||||
|
}
|
||||||
|
if len(output.Warnings) != 0 {
|
||||||
|
t.Fatalf("warnings = %#v, want grounded descriptions without warnings", output.Warnings)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type sceneDescriptionLLM struct{}
|
||||||
|
|
||||||
|
func (sceneDescriptionLLM) CompleteStructured(ctx context.Context, req contracts.StructuredCompletionRequest, out any) (contracts.StructuredCompletionResponse, error) {
|
||||||
|
if err := ctx.Err(); err != nil {
|
||||||
|
return contracts.StructuredCompletionResponse{}, err
|
||||||
|
}
|
||||||
|
if req.PromptID != sceneextract.PromptID {
|
||||||
|
return contracts.StructuredCompletionResponse{}, fmt.Errorf("unexpected prompt %q", req.PromptID)
|
||||||
|
}
|
||||||
|
transcript := string(req.Inputs["transcript"].Content)
|
||||||
|
var content string
|
||||||
|
switch {
|
||||||
|
case strings.Contains(transcript, "Cure Wounds"):
|
||||||
|
content = `{"kind":"narrative","title":" Aria casts Cure Wounds ","summary":" Aria casts Cure Wounds. "}`
|
||||||
|
case strings.Contains(transcript, "Shield"):
|
||||||
|
content = `{"kind":"combat","title":"Bandit mage casts Shield","summary":"The bandit mage casts Shield."}`
|
||||||
|
default:
|
||||||
|
return contracts.StructuredCompletionResponse{}, fmt.Errorf("unexpected transcript material %q", transcript)
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal([]byte(content), out); err != nil {
|
||||||
|
return contracts.StructuredCompletionResponse{}, fmt.Errorf("populate structured response: %w", err)
|
||||||
|
}
|
||||||
|
return contracts.StructuredCompletionResponse{Content: []byte(content), Provider: "test", Model: "deterministic", ProfileID: req.ProfileID}, nil
|
||||||
|
}
|
||||||
@@ -5,10 +5,12 @@ import (
|
|||||||
combatextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/combatturns"
|
combatextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/combatturns"
|
||||||
interactionextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcinteractions"
|
interactionextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcinteractions"
|
||||||
npcextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcs"
|
npcextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcs"
|
||||||
|
scenedescriptionextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/scenedescriptions"
|
||||||
spellextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/spells"
|
spellextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/spells"
|
||||||
combatnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/combatturns"
|
combatnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/combatturns"
|
||||||
interactionnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcinteractions"
|
interactionnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcinteractions"
|
||||||
npcnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcs"
|
npcnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcs"
|
||||||
|
scenedescriptionnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/scenedescriptions"
|
||||||
spellnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/spells"
|
spellnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/spells"
|
||||||
combatinvariants "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/combatturns/invariants"
|
combatinvariants "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/combatturns/invariants"
|
||||||
combatshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/combatturns/shape"
|
combatshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/combatturns/shape"
|
||||||
@@ -23,6 +25,10 @@ import (
|
|||||||
npcshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcs/shape"
|
npcshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcs/shape"
|
||||||
npcsourcerefs "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcs/source_refs"
|
npcsourcerefs "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcs/source_refs"
|
||||||
npcrelatedness "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcs/source_relatedness"
|
npcrelatedness "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcs/source_relatedness"
|
||||||
|
sceneinvariants "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/scenedescriptions/invariants"
|
||||||
|
sceneshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/scenedescriptions/shape"
|
||||||
|
scenerefs "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/scenedescriptions/source_refs"
|
||||||
|
scenerelatedness "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/scenedescriptions/source_relatedness"
|
||||||
spellcatalog "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/spells/catalog"
|
spellcatalog "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/spells/catalog"
|
||||||
spellshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/spells/shape"
|
spellshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/spells/shape"
|
||||||
spellsourcerefs "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/spells/source_refs"
|
spellsourcerefs "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/spells/source_refs"
|
||||||
@@ -144,5 +150,32 @@ func registerDefaultChains(registry *pipeline.ValidatorChainRegistry) error {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}},
|
}},
|
||||||
|
{name: "scene descriptions validator chain", register: func() error {
|
||||||
|
return registry.Register(pipeline.ValidatorChainMapping{
|
||||||
|
Stage: pipeline.StageExtract,
|
||||||
|
Module: scenedescriptionextract.Key,
|
||||||
|
Validators: []pipeline.ModuleBinding{
|
||||||
|
pipeline.Binding(validjson.Key),
|
||||||
|
pipeline.Binding(sceneshape.Key),
|
||||||
|
pipeline.Binding(scenerefs.Key),
|
||||||
|
pipeline.Binding(validjsonschema.Key),
|
||||||
|
pipeline.Binding(scenerelatedness.Key),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}},
|
||||||
|
{name: "scene descriptions normalize validator chain", register: func() error {
|
||||||
|
return registry.Register(pipeline.ValidatorChainMapping{
|
||||||
|
Stage: pipeline.StageNormalize,
|
||||||
|
Module: scenedescriptionnormalize.Key,
|
||||||
|
Validators: []pipeline.ModuleBinding{
|
||||||
|
pipeline.Binding(validjson.Key),
|
||||||
|
pipeline.Binding(sceneshape.Key),
|
||||||
|
pipeline.Binding(sceneinvariants.Key),
|
||||||
|
pipeline.Binding(scenerefs.Key),
|
||||||
|
pipeline.Binding(validjsonschema.Key),
|
||||||
|
pipeline.Binding(scenerelatedness.Key),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,25 @@ func appendNPCInteractionLists(values []dnd.NPCInteractionList) (dnd.NPCInteract
|
|||||||
return combined, nil
|
return combined, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func appendSceneDescriptionLists(values []dnd.SceneDescriptionList) (dnd.SceneDescriptionList, error) {
|
||||||
|
count := 0
|
||||||
|
present := false
|
||||||
|
for _, value := range values {
|
||||||
|
if value.Scenes != nil {
|
||||||
|
present = true
|
||||||
|
}
|
||||||
|
count += len(value.Scenes)
|
||||||
|
}
|
||||||
|
if !present {
|
||||||
|
return dnd.SceneDescriptionList{}, nil
|
||||||
|
}
|
||||||
|
combined := dnd.SceneDescriptionList{Scenes: make([]dnd.SceneDescription, 0, count)}
|
||||||
|
for _, value := range values {
|
||||||
|
combined.Scenes = append(combined.Scenes, value.Scenes...)
|
||||||
|
}
|
||||||
|
return combined, nil
|
||||||
|
}
|
||||||
|
|
||||||
func cloneCombatTurn(value dnd.CombatTurn) dnd.CombatTurn {
|
func cloneCombatTurn(value dnd.CombatTurn) dnd.CombatTurn {
|
||||||
clone := value
|
clone := value
|
||||||
if value.SourceRefs != nil {
|
if value.SourceRefs != nil {
|
||||||
|
|||||||
@@ -8,14 +8,17 @@ import (
|
|||||||
combatcodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/combatturns"
|
combatcodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/combatturns"
|
||||||
interactioncodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcinteractions"
|
interactioncodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcinteractions"
|
||||||
npccodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcs"
|
npccodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcs"
|
||||||
|
scenedescriptioncodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/scenedescriptions"
|
||||||
spellcodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/spells"
|
spellcodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/spells"
|
||||||
combatextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/combatturns"
|
combatextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/combatturns"
|
||||||
interactionextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcinteractions"
|
interactionextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcinteractions"
|
||||||
npcextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcs"
|
npcextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcs"
|
||||||
|
scenedescriptionextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/scenedescriptions"
|
||||||
spellextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/spells"
|
spellextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/spells"
|
||||||
combatnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/combatturns"
|
combatnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/combatturns"
|
||||||
interactionnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcinteractions"
|
interactionnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcinteractions"
|
||||||
npcnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcs"
|
npcnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcs"
|
||||||
|
scenedescriptionnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/scenedescriptions"
|
||||||
spellnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/spells"
|
spellnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/spells"
|
||||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/generic/merge/appendorder"
|
"gitea.maximumdirect.net/eric/notarius/internal/modules/generic/merge/appendorder"
|
||||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/generic/normalize/noop"
|
"gitea.maximumdirect.net/eric/notarius/internal/modules/generic/normalize/noop"
|
||||||
@@ -28,11 +31,15 @@ func registerModules(registries pipeline.Registries) error {
|
|||||||
{name: "npcs codec", register: func() error { return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, npccodec.New()) }},
|
{name: "npcs codec", register: func() error { return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, npccodec.New()) }},
|
||||||
{name: "combat turns codec", register: func() error { return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, combatcodec.New()) }},
|
{name: "combat turns codec", register: func() error { return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, combatcodec.New()) }},
|
||||||
{name: "npc interactions codec", register: func() error { return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, interactioncodec.New()) }},
|
{name: "npc interactions codec", register: func() error { return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, interactioncodec.New()) }},
|
||||||
|
{name: "scene descriptions codec", register: func() error {
|
||||||
|
return pipeline.RegisterArtifactCodec(registries.ArtifactCodecs, scenedescriptioncodec.New())
|
||||||
|
}},
|
||||||
{name: "scenes chunker", register: func() error { return scenes.Register(registries.Chunkers) }},
|
{name: "scenes chunker", register: func() error { return scenes.Register(registries.Chunkers) }},
|
||||||
{name: "spells extractor", register: func() error { return spellextract.Register(registries.Extractors) }},
|
{name: "spells extractor", register: func() error { return spellextract.Register(registries.Extractors) }},
|
||||||
{name: "npcs extractor", register: func() error { return npcextract.Register(registries.Extractors) }},
|
{name: "npcs extractor", register: func() error { return npcextract.Register(registries.Extractors) }},
|
||||||
{name: "combat turns extractor", register: func() error { return combatextract.Register(registries.Extractors) }},
|
{name: "combat turns extractor", register: func() error { return combatextract.Register(registries.Extractors) }},
|
||||||
{name: "npc interactions extractor", register: func() error { return interactionextract.Register(registries.Extractors) }},
|
{name: "npc interactions extractor", register: func() error { return interactionextract.Register(registries.Extractors) }},
|
||||||
|
{name: "scene descriptions extractor", register: func() error { return scenedescriptionextract.Register(registries.Extractors) }},
|
||||||
{name: "spell-list appendorder merger", register: func() error {
|
{name: "spell-list appendorder merger", register: func() error {
|
||||||
return appendorder.RegisterTyped(registries.Mergers, dnd.SpellListKind, appendSpellLists)
|
return appendorder.RegisterTyped(registries.Mergers, dnd.SpellListKind, appendSpellLists)
|
||||||
}},
|
}},
|
||||||
@@ -45,10 +52,14 @@ func registerModules(registries pipeline.Registries) error {
|
|||||||
{name: "npc-interaction-list appendorder merger", register: func() error {
|
{name: "npc-interaction-list appendorder merger", register: func() error {
|
||||||
return appendorder.RegisterTyped(registries.Mergers, dnd.NPCInteractionListKind, appendNPCInteractionLists)
|
return appendorder.RegisterTyped(registries.Mergers, dnd.NPCInteractionListKind, appendNPCInteractionLists)
|
||||||
}},
|
}},
|
||||||
|
{name: "scene-description-list appendorder merger", register: func() error {
|
||||||
|
return appendorder.RegisterTyped(registries.Mergers, dnd.SceneDescriptionListKind, appendSceneDescriptionLists)
|
||||||
|
}},
|
||||||
{name: "spells normalizer", register: func() error { return spellnormalize.Register(registries.Normalizers) }},
|
{name: "spells normalizer", register: func() error { return spellnormalize.Register(registries.Normalizers) }},
|
||||||
{name: "npcs normalizer", register: func() error { return npcnormalize.Register(registries.Normalizers) }},
|
{name: "npcs normalizer", register: func() error { return npcnormalize.Register(registries.Normalizers) }},
|
||||||
{name: "combat turns normalizer", register: func() error { return combatnormalize.Register(registries.Normalizers) }},
|
{name: "combat turns normalizer", register: func() error { return combatnormalize.Register(registries.Normalizers) }},
|
||||||
{name: "npc interactions normalizer", register: func() error { return interactionnormalize.Register(registries.Normalizers) }},
|
{name: "npc interactions normalizer", register: func() error { return interactionnormalize.Register(registries.Normalizers) }},
|
||||||
|
{name: "scene descriptions normalizer", register: func() error { return scenedescriptionnormalize.Register(registries.Normalizers) }},
|
||||||
{name: "spell-list noop normalizer", register: func() error {
|
{name: "spell-list noop normalizer", register: func() error {
|
||||||
return noop.RegisterTyped[dnd.SpellList](registries.Normalizers, dnd.SpellListKind)
|
return noop.RegisterTyped[dnd.SpellList](registries.Normalizers, dnd.SpellListKind)
|
||||||
}},
|
}},
|
||||||
@@ -61,6 +72,9 @@ func registerModules(registries pipeline.Registries) error {
|
|||||||
{name: "npc-interaction-list noop normalizer", register: func() error {
|
{name: "npc-interaction-list noop normalizer", register: func() error {
|
||||||
return noop.RegisterTyped[dnd.NPCInteractionList](registries.Normalizers, dnd.NPCInteractionListKind)
|
return noop.RegisterTyped[dnd.NPCInteractionList](registries.Normalizers, dnd.NPCInteractionListKind)
|
||||||
}},
|
}},
|
||||||
|
{name: "scene-description-list noop normalizer", register: func() error {
|
||||||
|
return noop.RegisterTyped[dnd.SceneDescriptionList](registries.Normalizers, dnd.SceneDescriptionListKind)
|
||||||
|
}},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,5 +85,6 @@ func registerPromptAssets(assets *llm.AssetRegistry) error {
|
|||||||
{name: "npcs prompt assets", register: func() error { return npcextract.RegisterPromptAssets(assets) }},
|
{name: "npcs prompt assets", register: func() error { return npcextract.RegisterPromptAssets(assets) }},
|
||||||
{name: "combat turns prompt assets", register: func() error { return combatextract.RegisterPromptAssets(assets) }},
|
{name: "combat turns prompt assets", register: func() error { return combatextract.RegisterPromptAssets(assets) }},
|
||||||
{name: "npc interactions prompt assets", register: func() error { return interactionextract.RegisterPromptAssets(assets) }},
|
{name: "npc interactions prompt assets", register: func() error { return interactionextract.RegisterPromptAssets(assets) }},
|
||||||
|
{name: "scene descriptions prompt assets", register: func() error { return scenedescriptionextract.RegisterPromptAssets(assets) }},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,12 @@ import (
|
|||||||
combatextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/combatturns"
|
combatextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/combatturns"
|
||||||
interactionextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcinteractions"
|
interactionextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcinteractions"
|
||||||
npcextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcs"
|
npcextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcs"
|
||||||
|
scenedescriptionextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/scenedescriptions"
|
||||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/spells"
|
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/spells"
|
||||||
combatnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/combatturns"
|
combatnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/combatturns"
|
||||||
interactionnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcinteractions"
|
interactionnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcinteractions"
|
||||||
npcnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcs"
|
npcnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcs"
|
||||||
|
scenedescriptionnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/scenedescriptions"
|
||||||
spellnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/spells"
|
spellnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/spells"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -29,14 +31,15 @@ func TestRegisterAddsDNDFamily(t *testing.T) {
|
|||||||
t.Fatalf("Register() error = %v, want nil", err)
|
t.Fatalf("Register() error = %v, want nil", err)
|
||||||
}
|
}
|
||||||
assertContainsKeys(t, "chunkers", registries.Chunkers.RegisteredKeys(), []string{"dnd/scenes"})
|
assertContainsKeys(t, "chunkers", registries.Chunkers.RegisteredKeys(), []string{"dnd/scenes"})
|
||||||
assertContainsKeys(t, "extractors", registries.Extractors.RegisteredKeys(), []string{"dnd/spells", npcextract.Key, combatextract.Key, interactionextract.Key})
|
assertContainsKeys(t, "extractors", registries.Extractors.RegisteredKeys(), []string{"dnd/spells", npcextract.Key, combatextract.Key, interactionextract.Key, scenedescriptionextract.Key})
|
||||||
assertContainsKeys(t, "normalizers", registries.Normalizers.RegisteredKeys(), []string{spellnormalize.Key, npcnormalize.Key, combatnormalize.Key, interactionnormalize.Key, pipeline.DefaultNormalizeModule})
|
assertContainsKeys(t, "normalizers", registries.Normalizers.RegisteredKeys(), []string{spellnormalize.Key, npcnormalize.Key, combatnormalize.Key, interactionnormalize.Key, scenedescriptionnormalize.Key, pipeline.DefaultNormalizeModule})
|
||||||
assertContainsArtifactKinds(t, registries.ArtifactCodecs.RegisteredKinds(), []contracts.ArtifactKind{dnd.SpellListKind, dnd.NPCListKind, dnd.CombatTurnListKind, dnd.NPCInteractionListKind})
|
assertContainsArtifactKinds(t, registries.ArtifactCodecs.RegisteredKinds(), []contracts.ArtifactKind{dnd.SpellListKind, dnd.NPCListKind, dnd.CombatTurnListKind, dnd.NPCInteractionListKind, dnd.SceneDescriptionListKind})
|
||||||
assertContainsArtifactKinds(t, registries.Mergers.RegisteredArtifactKinds(pipeline.DefaultMergeModule), []contracts.ArtifactKind{dnd.SpellListKind, dnd.NPCListKind, dnd.CombatTurnListKind, dnd.NPCInteractionListKind})
|
assertContainsArtifactKinds(t, registries.Mergers.RegisteredArtifactKinds(pipeline.DefaultMergeModule), []contracts.ArtifactKind{dnd.SpellListKind, dnd.NPCListKind, dnd.CombatTurnListKind, dnd.NPCInteractionListKind, dnd.SceneDescriptionListKind})
|
||||||
assertContainsArtifactKinds(t, registries.Normalizers.RegisteredArtifactKinds(pipeline.DefaultNormalizeModule), []contracts.ArtifactKind{dnd.SpellListKind, dnd.NPCListKind, dnd.CombatTurnListKind, dnd.NPCInteractionListKind})
|
assertContainsArtifactKinds(t, registries.Normalizers.RegisteredArtifactKinds(pipeline.DefaultNormalizeModule), []contracts.ArtifactKind{dnd.SpellListKind, dnd.NPCListKind, dnd.CombatTurnListKind, dnd.NPCInteractionListKind, dnd.SceneDescriptionListKind})
|
||||||
assertContainsArtifactKinds(t, registries.Normalizers.RegisteredArtifactKinds(npcnormalize.Key), []contracts.ArtifactKind{dnd.NPCListKind})
|
assertContainsArtifactKinds(t, registries.Normalizers.RegisteredArtifactKinds(npcnormalize.Key), []contracts.ArtifactKind{dnd.NPCListKind})
|
||||||
assertContainsArtifactKinds(t, registries.Normalizers.RegisteredArtifactKinds(combatnormalize.Key), []contracts.ArtifactKind{dnd.CombatTurnListKind})
|
assertContainsArtifactKinds(t, registries.Normalizers.RegisteredArtifactKinds(combatnormalize.Key), []contracts.ArtifactKind{dnd.CombatTurnListKind})
|
||||||
assertContainsArtifactKinds(t, registries.Normalizers.RegisteredArtifactKinds(interactionnormalize.Key), []contracts.ArtifactKind{dnd.NPCInteractionListKind})
|
assertContainsArtifactKinds(t, registries.Normalizers.RegisteredArtifactKinds(interactionnormalize.Key), []contracts.ArtifactKind{dnd.NPCInteractionListKind})
|
||||||
|
assertContainsArtifactKinds(t, registries.Normalizers.RegisteredArtifactKinds(scenedescriptionnormalize.Key), []contracts.ArtifactKind{dnd.SceneDescriptionListKind})
|
||||||
assertContainsKeys(t, "validators", registries.Validators.RegisteredKeys(), []string{
|
assertContainsKeys(t, "validators", registries.Validators.RegisteredKeys(), []string{
|
||||||
"extract/dnd/npcs/shape",
|
"extract/dnd/npcs/shape",
|
||||||
"extract/dnd/npcs/source_refs",
|
"extract/dnd/npcs/source_refs",
|
||||||
@@ -55,6 +58,10 @@ func TestRegisterAddsDNDFamily(t *testing.T) {
|
|||||||
"extract/dnd/npc-interactions/source_refs",
|
"extract/dnd/npc-interactions/source_refs",
|
||||||
"extract/dnd/npc-interactions/source_relatedness",
|
"extract/dnd/npc-interactions/source_relatedness",
|
||||||
"normalize/dnd/npc-interactions/invariants",
|
"normalize/dnd/npc-interactions/invariants",
|
||||||
|
"extract/dnd/scene-descriptions/shape",
|
||||||
|
"extract/dnd/scene-descriptions/source_refs",
|
||||||
|
"extract/dnd/scene-descriptions/source_relatedness",
|
||||||
|
"normalize/dnd/scene-descriptions/invariants",
|
||||||
"generic/always_accept",
|
"generic/always_accept",
|
||||||
"generic/always_reject",
|
"generic/always_reject",
|
||||||
})
|
})
|
||||||
@@ -137,6 +144,27 @@ func TestRegisterAddsDNDFamily(t *testing.T) {
|
|||||||
if got := registries.ValidatorChains.Validators(pipeline.StageNormalize, interactionnormalize.Key); !reflect.DeepEqual(got, interactionNormalizeChain) {
|
if got := registries.ValidatorChains.Validators(pipeline.StageNormalize, interactionnormalize.Key); !reflect.DeepEqual(got, interactionNormalizeChain) {
|
||||||
t.Fatalf("NPC interaction normalize validator chain = %#v, want %#v", got, interactionNormalizeChain)
|
t.Fatalf("NPC interaction normalize validator chain = %#v, want %#v", got, interactionNormalizeChain)
|
||||||
}
|
}
|
||||||
|
sceneExtractChain := []pipeline.ModuleBinding{
|
||||||
|
pipeline.Binding("generic/valid_json"),
|
||||||
|
pipeline.Binding("extract/dnd/scene-descriptions/shape"),
|
||||||
|
pipeline.Binding("extract/dnd/scene-descriptions/source_refs"),
|
||||||
|
pipeline.Binding("generic/valid_json_schema"),
|
||||||
|
pipeline.Binding("extract/dnd/scene-descriptions/source_relatedness"),
|
||||||
|
}
|
||||||
|
if got := registries.ValidatorChains.Validators(pipeline.StageExtract, scenedescriptionextract.Key); !reflect.DeepEqual(got, sceneExtractChain) {
|
||||||
|
t.Fatalf("scene description extract validator chain = %#v, want %#v", got, sceneExtractChain)
|
||||||
|
}
|
||||||
|
sceneNormalizeChain := []pipeline.ModuleBinding{
|
||||||
|
pipeline.Binding("generic/valid_json"),
|
||||||
|
pipeline.Binding("extract/dnd/scene-descriptions/shape"),
|
||||||
|
pipeline.Binding("normalize/dnd/scene-descriptions/invariants"),
|
||||||
|
pipeline.Binding("extract/dnd/scene-descriptions/source_refs"),
|
||||||
|
pipeline.Binding("generic/valid_json_schema"),
|
||||||
|
pipeline.Binding("extract/dnd/scene-descriptions/source_relatedness"),
|
||||||
|
}
|
||||||
|
if got := registries.ValidatorChains.Validators(pipeline.StageNormalize, scenedescriptionnormalize.Key); !reflect.DeepEqual(got, sceneNormalizeChain) {
|
||||||
|
t.Fatalf("scene description normalize validator chain = %#v, want %#v", got, sceneNormalizeChain)
|
||||||
|
}
|
||||||
if got := registries.ValidatorChains.Validators(pipeline.StageMerge, npcextract.Key); got != nil {
|
if got := registries.ValidatorChains.Validators(pipeline.StageMerge, npcextract.Key); got != nil {
|
||||||
t.Fatalf("NPC merge validator chain = %#v, want absent", got)
|
t.Fatalf("NPC merge validator chain = %#v, want absent", got)
|
||||||
}
|
}
|
||||||
@@ -172,6 +200,13 @@ func TestRegisterAddsDNDFamily(t *testing.T) {
|
|||||||
"dnd.npc_interactions/instructions.md",
|
"dnd.npc_interactions/instructions.md",
|
||||||
"dnd.npc_interactions/sharedassets/common-dnd-npcs.md",
|
"dnd.npc_interactions/sharedassets/common-dnd-npcs.md",
|
||||||
"dnd.npc_interactions/task.md",
|
"dnd.npc_interactions/task.md",
|
||||||
|
"dnd.scene_descriptions/dnd.scene_descriptions.yaml",
|
||||||
|
"dnd.scene_descriptions/instructions.md",
|
||||||
|
"dnd.scene_descriptions/sharedassets/common-dnd-identity.md",
|
||||||
|
"dnd.scene_descriptions/sharedassets/common-dnd-references.md",
|
||||||
|
"dnd.scene_descriptions/sharedassets/common-dnd-system.md",
|
||||||
|
"dnd.scene_descriptions/sharedassets/common-dnd-transcript.md",
|
||||||
|
"dnd.scene_descriptions/task.md",
|
||||||
})
|
})
|
||||||
assertAssetNamesContain(t, assets.SchemaFS, []string{
|
assertAssetNamesContain(t, assets.SchemaFS, []string{
|
||||||
"dnd_scenes.v1.json",
|
"dnd_scenes.v1.json",
|
||||||
@@ -179,6 +214,7 @@ func TestRegisterAddsDNDFamily(t *testing.T) {
|
|||||||
"dnd_npcs_llm.v1.json",
|
"dnd_npcs_llm.v1.json",
|
||||||
"dnd_combat_turns_llm.v1.json",
|
"dnd_combat_turns_llm.v1.json",
|
||||||
"dnd_npc_interactions_llm.v1.json",
|
"dnd_npc_interactions_llm.v1.json",
|
||||||
|
"dnd_scene_descriptions_llm.v1.json",
|
||||||
})
|
})
|
||||||
if spec, ok := registries.Chunkers.Spec("dnd/scenes"); !ok || spec.Key != "dnd/scenes" {
|
if spec, ok := registries.Chunkers.Spec("dnd/scenes"); !ok || spec.Key != "dnd/scenes" {
|
||||||
t.Fatalf("scene chunker spec = %#v, present = %t; want family-owned spec", spec, ok)
|
t.Fatalf("scene chunker spec = %#v, present = %t; want family-owned spec", spec, ok)
|
||||||
@@ -206,6 +242,14 @@ func TestRegisterAddsDNDFamily(t *testing.T) {
|
|||||||
if !extractOK || interactionExtractSpec.ArtifactKind != dnd.NPCInteractionListKind || !normalizeOK || interactionNormalizeSpec.ArtifactKind != dnd.NPCInteractionListKind || interactionNormalizeSpec.Stage != pipeline.StageNormalize {
|
if !extractOK || interactionExtractSpec.ArtifactKind != dnd.NPCInteractionListKind || !normalizeOK || interactionNormalizeSpec.ArtifactKind != dnd.NPCInteractionListKind || interactionNormalizeSpec.Stage != pipeline.StageNormalize {
|
||||||
t.Fatalf("NPC interaction specs = %#v / %#v, present = %t / %t", interactionExtractSpec, interactionNormalizeSpec, extractOK, normalizeOK)
|
t.Fatalf("NPC interaction specs = %#v / %#v, present = %t / %t", interactionExtractSpec, interactionNormalizeSpec, extractOK, normalizeOK)
|
||||||
}
|
}
|
||||||
|
sceneExtractSpec, sceneExtractOK := registries.Extractors.Spec(scenedescriptionextract.Key)
|
||||||
|
sceneNormalizeSpec, sceneNormalizeOK := registries.Normalizers.Spec(scenedescriptionnormalize.Key)
|
||||||
|
if !sceneExtractOK || sceneExtractSpec.ArtifactKind != dnd.SceneDescriptionListKind || !sceneNormalizeOK || sceneNormalizeSpec.ArtifactKind != dnd.SceneDescriptionListKind || sceneNormalizeSpec.Stage != pipeline.StageNormalize {
|
||||||
|
t.Fatalf("scene description specs = %#v / %#v, present = %t / %t", sceneExtractSpec, sceneNormalizeSpec, sceneExtractOK, sceneNormalizeOK)
|
||||||
|
}
|
||||||
|
if len(sceneExtractSpec.ReferenceSlots) != 3 || len(sceneNormalizeSpec.ReferenceSlots) != 0 {
|
||||||
|
t.Fatalf("scene description reference slots = %#v / %#v, want extractor campaign slots only", sceneExtractSpec.ReferenceSlots, sceneNormalizeSpec.ReferenceSlots)
|
||||||
|
}
|
||||||
extractRegistrySlot := referenceSlot(interactionExtractSpec.ReferenceSlots, "npcs")
|
extractRegistrySlot := referenceSlot(interactionExtractSpec.ReferenceSlots, "npcs")
|
||||||
normalizeRegistrySlot := referenceSlot(interactionNormalizeSpec.ReferenceSlots, "npcs")
|
normalizeRegistrySlot := referenceSlot(interactionNormalizeSpec.ReferenceSlots, "npcs")
|
||||||
if !extractRegistrySlot.Required || !reflect.DeepEqual(extractRegistrySlot.AcceptedArtifactKinds, []contracts.ArtifactKind{dnd.NPCListKind}) || !reflect.DeepEqual(extractRegistrySlot, normalizeRegistrySlot) {
|
if !extractRegistrySlot.Required || !reflect.DeepEqual(extractRegistrySlot.AcceptedArtifactKinds, []contracts.ArtifactKind{dnd.NPCListKind}) || !reflect.DeepEqual(extractRegistrySlot, normalizeRegistrySlot) {
|
||||||
@@ -270,6 +314,25 @@ func TestAppendNPCInteractionListsPreservesOrderPresenceAndOwnership(t *testing.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAppendSceneDescriptionListsPreservesOrderAndArrayPresence(t *testing.T) {
|
||||||
|
input := []dnd.SceneDescriptionList{
|
||||||
|
{},
|
||||||
|
{Scenes: []dnd.SceneDescription{}},
|
||||||
|
{Scenes: []dnd.SceneDescription{{ID: "first"}}},
|
||||||
|
{Scenes: []dnd.SceneDescription{{ID: "second"}}},
|
||||||
|
}
|
||||||
|
got, err := appendSceneDescriptionLists(input)
|
||||||
|
if err != nil || !reflect.DeepEqual(got.Scenes, []dnd.SceneDescription{{ID: "first"}, {ID: "second"}}) {
|
||||||
|
t.Fatalf("appendSceneDescriptionLists() = %#v, error = %v", got, err)
|
||||||
|
}
|
||||||
|
for _, values := range [][]dnd.SceneDescriptionList{nil, []dnd.SceneDescriptionList{{}, {}}} {
|
||||||
|
result, err := appendSceneDescriptionLists(values)
|
||||||
|
if err != nil || result.Scenes != nil {
|
||||||
|
t.Fatalf("nil-only merge = %#v, %v; want nil scenes", result, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAppendCombatTurnListsPreservesOrderPresenceAndOwnership(t *testing.T) {
|
func TestAppendCombatTurnListsPreservesOrderPresenceAndOwnership(t *testing.T) {
|
||||||
refs := []source.SourceRef{{SourceID: "session", StartUnitID: 1, EndUnitID: 1}}
|
refs := []source.SourceRef{{SourceID: "session", StartUnitID: 1, EndUnitID: 1}}
|
||||||
input := []dnd.CombatTurnList{
|
input := []dnd.CombatTurnList{
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ import (
|
|||||||
npcshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcs/shape"
|
npcshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcs/shape"
|
||||||
npcsourcerefs "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcs/source_refs"
|
npcsourcerefs "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcs/source_refs"
|
||||||
npcrelatedness "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcs/source_relatedness"
|
npcrelatedness "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcs/source_relatedness"
|
||||||
|
sceneinvariants "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/scenedescriptions/invariants"
|
||||||
|
sceneshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/scenedescriptions/shape"
|
||||||
|
scenerefs "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/scenedescriptions/source_refs"
|
||||||
|
scenerelatedness "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/scenedescriptions/source_relatedness"
|
||||||
spellcatalog "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/spells/catalog"
|
spellcatalog "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/spells/catalog"
|
||||||
spellshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/spells/shape"
|
spellshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/spells/shape"
|
||||||
spellsourcerefs "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/spells/source_refs"
|
spellsourcerefs "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/spells/source_refs"
|
||||||
@@ -43,6 +47,10 @@ func registerValidators(registries pipeline.Registries) error {
|
|||||||
{name: "npc interaction source references validator", register: func() error { return interactionrefs.Register(registries.Validators) }},
|
{name: "npc interaction source references validator", register: func() error { return interactionrefs.Register(registries.Validators) }},
|
||||||
{name: "npc interaction source relatedness validator", register: func() error { return interactionrelatedness.Register(registries.Validators) }},
|
{name: "npc interaction source relatedness validator", register: func() error { return interactionrelatedness.Register(registries.Validators) }},
|
||||||
{name: "npc interaction normalized invariants validator", register: func() error { return interactioninvariants.Register(registries.Validators) }},
|
{name: "npc interaction normalized invariants validator", register: func() error { return interactioninvariants.Register(registries.Validators) }},
|
||||||
|
{name: "scene description shape validator", register: func() error { return sceneshape.Register(registries.Validators) }},
|
||||||
|
{name: "scene description source references validator", register: func() error { return scenerefs.Register(registries.Validators) }},
|
||||||
|
{name: "scene description source relatedness validator", register: func() error { return scenerelatedness.Register(registries.Validators) }},
|
||||||
|
{name: "scene description normalized invariants validator", register: func() error { return sceneinvariants.Register(registries.Validators) }},
|
||||||
{name: "spell-list always accept validator", register: func() error {
|
{name: "spell-list always accept validator", register: func() error {
|
||||||
return alwaysaccept.RegisterTyped[dnd.SpellList](registries.Validators, dnd.SpellListKind)
|
return alwaysaccept.RegisterTyped[dnd.SpellList](registries.Validators, dnd.SpellListKind)
|
||||||
}},
|
}},
|
||||||
@@ -67,5 +75,11 @@ func registerValidators(registries pipeline.Registries) error {
|
|||||||
{name: "npc-interaction-list always reject validator", register: func() error {
|
{name: "npc-interaction-list always reject validator", register: func() error {
|
||||||
return alwaysreject.RegisterTyped[dnd.NPCInteractionList](registries.Validators, dnd.NPCInteractionListKind)
|
return alwaysreject.RegisterTyped[dnd.NPCInteractionList](registries.Validators, dnd.NPCInteractionListKind)
|
||||||
}},
|
}},
|
||||||
|
{name: "scene-description-list always accept validator", register: func() error {
|
||||||
|
return alwaysaccept.RegisterTyped[dnd.SceneDescriptionList](registries.Validators, dnd.SceneDescriptionListKind)
|
||||||
|
}},
|
||||||
|
{name: "scene-description-list always reject validator", register: func() error {
|
||||||
|
return alwaysreject.RegisterTyped[dnd.SceneDescriptionList](registries.Validators, dnd.SceneDescriptionListKind)
|
||||||
|
}},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user