Move NPC registry to canonical namespace

This commit is contained in:
2026-08-05 18:38:22 +00:00
parent 9653e06297
commit 3f4a1f2647
94 changed files with 320 additions and 320 deletions

View File

@@ -17,7 +17,7 @@ import (
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
combatcodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/combatturns"
npccodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcs"
npccodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcregistry"
scenecodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/scenedescriptions"
combatextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/combatturns"
combatnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/combatturns"
@@ -36,8 +36,8 @@ func TestProductionCombatPipelineRetriesMergesNormalizesAndWritesJSON(t *testing
PipelineID: "dnd-combat-fixture",
Catalog: catalog,
ReferenceOverrides: []pipeline.ReferenceBinding{
{Stage: pipeline.StageExtract, LaneID: "combat", SlotName: "npcs", Source: npcPayload.path, BindingSource: contracts.ReferenceBindingSourceCLI},
{Stage: pipeline.StageNormalize, LaneID: "combat", SlotName: "npcs", Source: npcPayload.path, BindingSource: contracts.ReferenceBindingSourceCLI},
{Stage: pipeline.StageExtract, LaneID: "combat", SlotName: "npc_registry", Source: npcPayload.path, BindingSource: contracts.ReferenceBindingSourceCLI},
{Stage: pipeline.StageNormalize, LaneID: "combat", SlotName: "npc_registry", Source: npcPayload.path, BindingSource: contracts.ReferenceBindingSourceCLI},
},
})
if err != nil {
@@ -278,8 +278,8 @@ func TestCombatPreparationRejectsMalformedOrOversizedNPCReferencesBeforeExecutio
PipelineID: "dnd-combat",
Catalog: catalog,
ReferenceOverrides: []pipeline.ReferenceBinding{
{Stage: pipeline.StageExtract, LaneID: "combat", SlotName: "npcs", Source: path, BindingSource: contracts.ReferenceBindingSourceCLI},
{Stage: pipeline.StageNormalize, LaneID: "combat", SlotName: "npcs", Source: path, BindingSource: contracts.ReferenceBindingSourceCLI},
{Stage: pipeline.StageExtract, LaneID: "combat", SlotName: "npc_registry", Source: path, BindingSource: contracts.ReferenceBindingSourceCLI},
{Stage: pipeline.StageNormalize, LaneID: "combat", SlotName: "npc_registry", Source: path, BindingSource: contracts.ReferenceBindingSourceCLI},
},
})
if err != nil {

View File

@@ -19,14 +19,14 @@ import (
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
combatcodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/combatturns"
npccodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcs"
npccodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcregistry"
scenecodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/scenedescriptions"
spellcodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/spells"
combatextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/combatturns"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcs"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcregistry"
sceneextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/scenedescriptions"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/spells"
npcnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcs"
npcnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcregistry"
)
func TestNPCOutputGroundsSpellAndCombatConsumersThroughOneOperation(t *testing.T) {
@@ -49,20 +49,20 @@ func TestNPCOutputGroundsSpellAndCombatConsumersThroughOneOperation(t *testing.T
t.Fatalf("Prepare() error = %v", err)
}
for name, value := range map[string]string{
"extract:npcs:dnd/npcs:mapping_policy": "dnd.npcs.extract_mapping.v2",
"normalize:npcs:dnd/npcs:identity_policy": "dnd.npc_registry.identity.v1",
"normalize:npcs:dnd/npcs:normalization_policy": "dnd.npcs.normalize.v3",
"normalize:npcs:dnd/npcs:semantic_context_policy": "dnd.entity_reconcile.context.v1:2",
"extract:spells:dnd/spells:mapping_policy": "dnd.spells.extract_mapping.v2",
"extract:combat:dnd/combat-turns:scene_gate_policy": "dnd.combat_turns.scene_gate.v1",
"extract:npc_registry:dnd/npc-registry:mapping_policy": "dnd.npc_registry.extract_mapping.v2",
"normalize:npc_registry:dnd/npc-registry:identity_policy": "dnd.npc_registry.identity.v1",
"normalize:npc_registry:dnd/npc-registry:normalization_policy": "dnd.npc_registry.normalize.v3",
"normalize:npc_registry:dnd/npc-registry:semantic_context_policy": "dnd.entity_reconcile.context.v1:2",
"extract:spells:dnd/spells:mapping_policy": "dnd.spells.extract_mapping.v2",
"extract:combat:dnd/combat-turns:scene_gate_policy": "dnd.combat_turns.scene_gate.v1",
} {
assertFingerprintValue(t, prepared.CheckpointFingerprints(), name, value)
}
for _, name := range []string{
"extract:npcs:dnd/npcs:prompt",
"extract:npcs:dnd/npcs:response_schema",
"normalize:npcs:dnd/npcs:prompt",
"normalize:npcs:dnd/npcs:response_schema",
"extract:npc_registry:dnd/npc-registry:prompt",
"extract:npc_registry:dnd/npc-registry:response_schema",
"normalize:npc_registry:dnd/npc-registry:prompt",
"normalize:npc_registry:dnd/npc-registry:response_schema",
"extract:spells:dnd/spells:prompt",
"extract:spells:dnd/spells:response_schema",
"extract:spells:dnd/spells:npc_registry",
@@ -87,14 +87,14 @@ func TestNPCOutputGroundsSpellAndCombatConsumersThroughOneOperation(t *testing.T
if len(output.Rejected) != 0 || len(output.NormalizeOutputs) != 4 {
t.Fatalf("run outputs = %#v rejected = %#v, want NPC, scene, spell, and combat outputs", output.NormalizeOutputs, output.Rejected)
}
wantSchemas := map[string]string{"npcs": npccodec.SchemaID, "scene-descriptions": scenecodec.SchemaID, "spells": spellcodec.SchemaID, "combat": combatcodec.SchemaID}
wantSchemas := map[string]string{"npc_registry": npccodec.SchemaID, "scene-descriptions": scenecodec.SchemaID, "spells": spellcodec.SchemaID, "combat": combatcodec.SchemaID}
for _, serialized := range output.NormalizeOutputs {
if serialized.Artifact.Schema.ID != wantSchemas[serialized.LaneID] || serialized.Artifact.Schema.Version != "v1" {
t.Fatalf("%s artifact schema = %#v, want minimal v1 identity", serialized.LaneID, serialized.Artifact.Schema)
}
}
wantExtractorIdentity := map[string]struct{ promptID, schemaID string }{
"npcs": {npcs.PromptID, npcs.ResponseSchemaID},
"npc_registry": {npcregistry.PromptID, npcregistry.ResponseSchemaID},
"scene-descriptions": {sceneextract.PromptID, sceneextract.ResponseSchemaID},
"spells": {spells.PromptID, spells.ResponseSchemaID},
"combat": {combatextract.PromptID, combatextract.ResponseSchemaID},
@@ -112,13 +112,13 @@ func TestNPCOutputGroundsSpellAndCombatConsumersThroughOneOperation(t *testing.T
for _, serialized := range output.NormalizeOutputs {
seenSteps[serialized.LaneID] = serialized.StepID
switch serialized.LaneID {
case "npcs":
case "npc_registry":
npcPayload = append([]byte(nil), serialized.Artifact.Content...)
case "scene-descriptions":
scenePayload = append([]byte(nil), serialized.Artifact.Content...)
}
}
if seenSteps["npcs"] != "identify-npcs" || seenSteps["scene-descriptions"] != "identify-npcs" || seenSteps["spells"] != "grounded-events" || seenSteps["combat"] != "grounded-events" {
if seenSteps["npc_registry"] != "identify-npcs" || seenSteps["scene-descriptions"] != "identify-npcs" || seenSteps["spells"] != "grounded-events" || seenSteps["combat"] != "grounded-events" {
t.Fatalf("normalized output steps = %#v, want ordered producer and consumer steps", seenSteps)
}
if len(npcPayload) == 0 {
@@ -152,7 +152,7 @@ func TestNPCOutputGroundsSpellAndCombatConsumersThroughOneOperation(t *testing.T
if request.PromptID != spells.PromptID && request.PromptID != combatextract.PromptID {
continue
}
input := request.Inputs["npcs"]
input := request.Inputs["npc_registry"]
if input.MediaType != npccodec.MediaType || input.Digest != projectionDigest || string(input.Content) != string(projection) || input.OriginURI != "" {
t.Fatalf("%s NPC prompt input = %#v, want names-only generated registry", request.PromptID, input)
}
@@ -182,7 +182,7 @@ func TestNPCOutputGroundsSpellAndCombatConsumersThroughOneOperation(t *testing.T
provenanceCount := 0
for _, reference := range output.Manifest.References {
if reference.SlotName != "npcs" {
if reference.SlotName != "npc_registry" {
continue
}
provenanceCount++
@@ -261,7 +261,7 @@ func TestProductionDNDOutputPublishesSelectedEvidenceContext(t *testing.T) {
configValue := loadGroundedPipelineConfig(t)
profile := configValue.Pipelines["dnd-npc-grounded"]
profile.Output.Options = map[string]any{"evidence_context": map[string]any{
"enabled": true, "window_units": 0, "lanes": []any{"npcs", "spells", "combat"},
"enabled": true, "window_units": 0, "lanes": []any{"npc_registry", "spells", "combat"},
}}
configValue.Pipelines["dnd-npc-grounded"] = profile
raw := strings.NewReplacer(
@@ -277,14 +277,14 @@ func TestProductionDNDOutputPublishesSelectedEvidenceContext(t *testing.T) {
if err != nil {
t.Fatalf("Decode(evidence context) error = %v", err)
}
if !reflect.DeepEqual(value.SelectedLanes, []string{"combat", "npcs", "spells"}) {
if !reflect.DeepEqual(value.SelectedLanes, []string{"combat", "npc_registry", "spells"}) {
t.Fatalf("selected lanes = %#v, want configured production lanes without scene descriptions", value.SelectedLanes)
}
if len(value.Contexts) != 2 || len(value.Contexts[0].Units) != 1 || len(value.Contexts[1].Units) != 1 || value.Contexts[0].Units[0].ID != 10 || value.Contexts[1].Units[0].ID != 20 {
t.Fatalf("evidence contexts = %#v, want source-position union with non-monotonic unit IDs", value.Contexts)
}
firstRefs := value.Contexts[0].EvidenceRefs
if len(firstRefs) != 3 || firstRefs[0].LaneID != "combat" || firstRefs[1].LaneID != "npcs" || firstRefs[2].LaneID != "spells" {
if len(firstRefs) != 3 || firstRefs[0].LaneID != "combat" || firstRefs[1].LaneID != "npc_registry" || firstRefs[2].LaneID != "spells" {
t.Fatalf("first context evidence = %#v, want overlapping selected lane references", firstRefs)
}
for _, context := range value.Contexts {
@@ -538,7 +538,7 @@ func (client *groundedDNDLLMClient) CompleteStructured(ctx context.Context, requ
thirdUnitID = 3
}
switch request.PromptID {
case npcs.PromptID:
case npcregistry.PromptID:
payload = map[string]any{"npcs": []any{
map[string]any{
"name": "Mira Thorn", "source_refs": []any{map[string]int{"start_unit_id": firstUnitID, "end_unit_id": firstUnitID}},

View File

@@ -15,10 +15,10 @@ import (
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
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/npcregistry"
interactionextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcinteractions"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcs"
npcnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcs"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcregistry"
npcnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcregistry"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/npcs/identity"
)
@@ -37,11 +37,11 @@ func TestNPCInteractionPipelineUsesAcceptedRegistryAndCurrentEvidence(t *testing
request := client.requestFor(t, interactionextract.PromptID)
wantRegistry := `{"npcs":[{"name":"Mira Thorn"},{"name":"Hooded Guard"}]}`
if got := string(request.Inputs["npcs"].Content); got != wantRegistry {
if got := string(request.Inputs["npc_registry"].Content); got != wantRegistry {
t.Fatalf("interaction registry input = %s, want names-only projection %s", got, wantRegistry)
}
if request.Inputs["npcs"].MediaType != npccodec.MediaType {
t.Fatalf("interaction registry media type = %q, want %q", request.Inputs["npcs"].MediaType, npccodec.MediaType)
if request.Inputs["npc_registry"].MediaType != npccodec.MediaType {
t.Fatalf("interaction registry media type = %q, want %q", request.Inputs["npc_registry"].MediaType, npccodec.MediaType)
}
serialized := normalizedLane(t, output, "interactions")
@@ -94,10 +94,10 @@ func TestSemanticNPCNormalizationCrossesOrderedRegistryHandoff(t *testing.T) {
if err != nil {
t.Fatalf("Run() error = %v", err)
}
if client.requestCount(npcs.PromptID) != 2 || client.requestCount(npcnormalize.PromptID) != 1 {
if client.requestCount(npcregistry.PromptID) != 2 || client.requestCount(npcnormalize.PromptID) != 1 {
t.Fatalf("prompt requests = %#v, want two extraction calls and one document normalization call", client.requests)
}
npcOutput := normalizedLane(t, output, "npcs")
npcOutput := normalizedLane(t, output, "npc_registry")
npcsValue, err := npccodec.New().Decode(npcOutput.Artifact.Content)
if err != nil {
t.Fatal(err)
@@ -113,7 +113,7 @@ func TestSemanticNPCNormalizationCrossesOrderedRegistryHandoff(t *testing.T) {
t.Fatalf("interaction output step = %q, want ordered downstream step", interactionOutput.StepID)
}
registryRequest := client.requestFor(t, interactionextract.PromptID)
if got := string(registryRequest.Inputs["npcs"].Content); got != `{"npcs":[{"name":"Mira Thorn"}]}` {
if got := string(registryRequest.Inputs["npc_registry"].Content); got != `{"npcs":[{"name":"Mira Thorn"}]}` {
t.Fatalf("downstream registry = %s, want one canonical names-only NPC", got)
}
manifestContent, err := json.Marshal(output.Manifest)
@@ -136,8 +136,8 @@ func TestNPCInteractionPipelineSkipsConsumerWhenNPCProducerIsRejected(t *testing
if err == nil {
t.Fatalf("Run() output = %#v, want missing generated NPC producer error", output)
}
if client.requestCount(npcs.PromptID) != 1 {
t.Fatalf("NPC requests = %d, want rejected producer", client.requestCount(npcs.PromptID))
if client.requestCount(npcregistry.PromptID) != 1 {
t.Fatalf("NPC requests = %d, want rejected producer", client.requestCount(npcregistry.PromptID))
}
if client.requestCount(interactionextract.PromptID) != 0 {
t.Fatalf("interaction requests = %d, want none after rejected producer", client.requestCount(interactionextract.PromptID))
@@ -214,7 +214,7 @@ func (client *npcInteractionLLMClient) CompleteStructured(ctx context.Context, r
var payload any
switch request.PromptID {
case npcs.PromptID:
case npcregistry.PromptID:
if client.rejectNPCs {
payload = map[string]any{"npcs": []any{map[string]any{
"name": "", "source_refs": []any{map[string]int{"start_unit_id": 1, "end_unit_id": 1}},
@@ -281,7 +281,7 @@ func (client *semanticNPCInteractionClient) CompleteStructured(_ context.Context
client.requests = append(client.requests, cloneStructuredCompletionRequest(request))
var payload any
switch request.PromptID {
case npcs.PromptID:
case npcregistry.PromptID:
client.npcCalls++
name := "Mira Thorn"
if client.npcCalls == 2 {

View File

@@ -12,14 +12,14 @@ import (
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
"gitea.maximumdirect.net/eric/notarius/internal/framework/llm"
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
npccodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcs"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcs"
npcnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcs"
npccodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcregistry"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcregistry"
npcnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcregistry"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/npcs/identity"
dndregister "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/register"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared/entityreconcile"
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"
npcshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcregistry/shape"
npcregistrysourcerefs "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcregistry/source_refs"
genericregister "gitea.maximumdirect.net/eric/notarius/internal/modules/generic/register"
"gitea.maximumdirect.net/eric/notarius/internal/modules/seriatim/input/transcript"
seriatimregister "gitea.maximumdirect.net/eric/notarius/internal/modules/seriatim/register"
@@ -33,7 +33,7 @@ func TestRunnerProcessesSeriatimInputWithProductionDNDNPCPipeline(t *testing.T)
}
registries := productionNPCRegistries(t)
configValue := loadNPCPipelineConfig(t)
effective, err := configValue.Resolve(config.ResolveInput{PipelineID: "dnd-npcs-fixture", Catalog: moduleCatalog(registries)})
effective, err := configValue.Resolve(config.ResolveInput{PipelineID: "dnd-npc-registry-fixture", Catalog: moduleCatalog(registries)})
if err != nil {
t.Fatalf("Resolve() error = %v, want nil", err)
}
@@ -62,7 +62,7 @@ func TestRunnerProcessesSeriatimInputWithProductionDNDNPCPipeline(t *testing.T)
t.Fatalf("normalize outputs = %d, want one NPC output; rejected=%#v", len(output.NormalizeOutputs), output.Rejected)
}
serialized := output.NormalizeOutputs[0]
if serialized.LaneID != "npcs" || serialized.NormalizerKey != npcs.Key || serialized.Artifact.Schema.ID != npccodec.SchemaID || serialized.Artifact.Schema.Version != npccodec.SchemaVersion {
if serialized.LaneID != "npc_registry" || serialized.NormalizerKey != npcregistry.Key || serialized.Artifact.Schema.ID != npccodec.SchemaID || serialized.Artifact.Schema.Version != npccodec.SchemaVersion {
t.Fatalf("serialized output = %#v, want durable NPC lane schema", serialized)
}
value, err := npccodec.New().Decode(serialized.Artifact.Content)
@@ -93,7 +93,7 @@ func TestRunnerProcessesSeriatimInputWithProductionDNDNPCPipeline(t *testing.T)
t.Fatalf("manifest = %#v, want approved NPC lane", output.Manifest)
}
lane := output.Manifest.ArtifactLanes[0]
if lane.ID != "npcs" || lane.Extractor != npcs.Key || lane.Merger != pipeline.DefaultMergeModule || lane.Normalizer != npcs.Key {
if lane.ID != "npc_registry" || lane.Extractor != npcregistry.Key || lane.Merger != pipeline.DefaultMergeModule || lane.Normalizer != npcregistry.Key {
t.Fatalf("manifest lane = %#v, want NPC production composition", lane)
}
normalizerMetadata, ok := lane.Metadata["normalizer"].(map[string]any)
@@ -102,7 +102,7 @@ func TestRunnerProcessesSeriatimInputWithProductionDNDNPCPipeline(t *testing.T)
}
var npcOutputFile *contracts.OutputFile
for index := range output.OutputFiles {
if output.OutputFiles[index].Name == "lanes/npcs.json" {
if output.OutputFiles[index].Name == "lanes/npc_registry.json" {
npcOutputFile = &output.OutputFiles[index]
break
}
@@ -110,7 +110,7 @@ func TestRunnerProcessesSeriatimInputWithProductionDNDNPCPipeline(t *testing.T)
if npcOutputFile == nil || npcOutputFile.ContentType != npccodec.MediaType {
t.Fatalf("output files = %#v, want JSON NPC lane file", output.OutputFiles)
}
if len(client.requests) != 2 || client.requests[0].PromptID != npcs.PromptID || client.requests[1].PromptID != npcnormalize.PromptID {
if len(client.requests) != 2 || client.requests[0].PromptID != npcregistry.PromptID || client.requests[1].PromptID != npcnormalize.PromptID {
t.Fatalf("LLM requests = %#v, want extraction and normalization prompt requests", client.requests)
}
}
@@ -118,7 +118,7 @@ func TestRunnerProcessesSeriatimInputWithProductionDNDNPCPipeline(t *testing.T)
func TestProductionNPCPipelineRoutesSemanticCandidatesToDeterministicValidators(t *testing.T) {
registries := productionNPCRegistries(t)
effective, err := loadNPCPipelineConfig(t).Resolve(config.ResolveInput{
PipelineID: "dnd-npcs-fixture",
PipelineID: "dnd-npc-registry-fixture",
Catalog: moduleCatalog(registries),
})
if err != nil {
@@ -145,14 +145,14 @@ func TestProductionNPCPipelineRoutesSemanticCandidatesToDeterministicValidators(
{
name: "nonpositive unit candidate",
response: []byte(`{"npcs":[{"name":"Mira Thorn","source_refs":[{"start_unit_id":0,"end_unit_id":1}]}]}`),
reasonCode: npcsourcerefs.ReasonCode,
validatorName: npcsourcerefs.Key,
reasonCode: npcregistrysourcerefs.ReasonCode,
validatorName: npcregistrysourcerefs.Key,
},
{
name: "unknown unit candidate",
response: []byte(`{"npcs":[{"name":"Mira Thorn","source_refs":[{"start_unit_id":99,"end_unit_id":99}]}]}`),
reasonCode: npcsourcerefs.ReasonCode,
validatorName: npcsourcerefs.Key,
reasonCode: npcregistrysourcerefs.ReasonCode,
validatorName: npcregistrysourcerefs.Key,
},
} {
t.Run(test.name, func(t *testing.T) {
@@ -194,12 +194,12 @@ func TestProductionNPCNormalizationRetryUsesFinalSafeProposal(t *testing.T) {
} {
t.Run(test.name, func(t *testing.T) {
cfg := loadNPCPipelineConfig(t)
profile := cfg.Pipelines["dnd-npcs-fixture"]
lane := profile.Artifacts["npcs"]
profile := cfg.Pipelines["dnd-npc-registry-fixture"]
lane := profile.Artifacts["npc_registry"]
lane.Normalize.Retries = test.retries
profile.Artifacts["npcs"] = lane
cfg.Pipelines["dnd-npcs-fixture"] = profile
effective, err := cfg.Resolve(config.ResolveInput{PipelineID: "dnd-npcs-fixture", Catalog: moduleCatalog(registries)})
profile.Artifacts["npc_registry"] = lane
cfg.Pipelines["dnd-npc-registry-fixture"] = profile
effective, err := cfg.Resolve(config.ResolveInput{PipelineID: "dnd-npc-registry-fixture", Catalog: moduleCatalog(registries)})
if err != nil {
t.Fatal(err)
}
@@ -243,9 +243,9 @@ func (client *fakeNPCProductionLLMClient) CompleteStructured(_ context.Context,
client.requests = append(client.requests, req)
var content []byte
switch req.PromptID {
case npcs.PromptID:
case npcregistry.PromptID:
if client.rawResponses != nil {
index := client.requestCount(npcs.PromptID) - 1
index := client.requestCount(npcregistry.PromptID) - 1
if index >= len(client.rawResponses) {
return contracts.StructuredCompletionResponse{}, fmt.Errorf("missing fake NPC response %d", index)
}
@@ -325,9 +325,9 @@ func moduleCatalog(registries pipeline.Registries) pipeline.ModuleCatalog {
func loadNPCPipelineConfig(t *testing.T) config.Config {
t.Helper()
data, err := os.ReadFile("testdata/dnd_npcs_pipeline.yml")
data, err := os.ReadFile("testdata/dnd_npc_registry_pipeline.yml")
if err != nil {
t.Fatalf("ReadFile(dnd_npcs_pipeline.yml) error = %v", err)
t.Fatalf("ReadFile(dnd_npc_registry_pipeline.yml) error = %v", err)
}
fileConfig, err := config.ParseFileConfigYAML(data)
if err != nil {

View File

@@ -13,18 +13,18 @@ pipelines:
steps:
- id: identify-npcs
artifacts:
npcs:
extract: dnd/npcs
normalize: dnd/npcs
npc_registry:
extract: dnd/npc-registry
normalize: dnd/npc-registry
scene-descriptions:
extract: dnd/scene-descriptions
normalize: dnd/scene-descriptions
- id: grounded-events
references:
npcs:
npc_registry:
artifact:
step: identify-npcs
lane: npcs
lane: npc_registry
scene_descriptions:
artifact:
step: identify-npcs

View File

@@ -13,15 +13,15 @@ pipelines:
steps:
- id: identify-npcs
artifacts:
npcs:
extract: dnd/npcs
normalize: dnd/npcs
npc_registry:
extract: dnd/npc-registry
normalize: dnd/npc-registry
- id: extract-interactions
references:
npcs:
npc_registry:
artifact:
step: identify-npcs
lane: npcs
lane: npc_registry
artifacts:
interactions:
extract: dnd/npc-interactions

View File

@@ -8,13 +8,13 @@ cache:
debug:
directory: ./notarius-debug
pipelines:
dnd-npcs-fixture:
dnd-npc-registry-fixture:
input: seriatim
chunk: generic
artifacts:
npcs:
npc_registry:
extract:
module: dnd/npcs
module: dnd/npc-registry
retries: 2
normalize: dnd/npcs
normalize: dnd/npc-registry
output: json