Move NPC occurrences to their canonical namespace

This commit is contained in:
2026-08-05 19:00:55 +00:00
parent 5e2ccffc0f
commit 2f61118e78
59 changed files with 518 additions and 518 deletions

View File

@@ -15,7 +15,7 @@ import (
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
combatturncodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/combatturns"
interactioncodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcinteractions"
occurrencecodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcoccurrences"
npccodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcregistry"
scenecodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/scenedescriptions"
npcregistry "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/npcs/registry"
@@ -27,7 +27,7 @@ const (
NPCRegistryReferenceSlot = npcregistry.ReferenceSlot
SceneDescriptionReferenceSlot = sceneregistry.ReferenceSlot
CombatTurnReferenceSlot = "combat_turns"
NPCInteractionReferenceSlot = "npc_interactions"
NPCOccurrenceReferenceSlot = "npc_occurrences"
ReferenceMaxBytes = 1048576
promptProjectionMediaType = "application/json"
)
@@ -67,10 +67,10 @@ func referenceSlots() []contracts.ReferenceSlot {
MaxBytes: ReferenceMaxBytes,
},
contracts.ReferenceSlot{
Name: NPCInteractionReferenceSlot,
Description: "Required NPC-interaction artifact used only as source-free enemy-event grounding.",
Name: NPCOccurrenceReferenceSlot,
Description: "Required NPC-occurrence artifact used only as source-free enemy-event grounding.",
Required: true,
AcceptedMediaTypes: []string{interactioncodec.MediaType},
AcceptedMediaTypes: []string{occurrencecodec.MediaType},
AcceptedArtifactKinds: []contracts.ArtifactKind{dnd.NPCOccurrenceListKind},
MaxBytes: ReferenceMaxBytes,
},
@@ -86,14 +86,14 @@ type groundingResolver struct {
npcs *npcregistry.Resolver
scenes *sceneregistry.Resolver
combatTurns *contracts.LLMInputMaterial
npcInteractions *contracts.LLMInputMaterial
combatTurns *contracts.LLMInputMaterial
npcOccurrences *contracts.LLMInputMaterial
}
type grounding struct {
npcInput contracts.LLMInputMaterial
combatTurnInput contracts.LLMInputMaterial
npcInteractionInput contracts.LLMInputMaterial
npcInput contracts.LLMInputMaterial
combatTurnInput contracts.LLMInputMaterial
npcOccurrenceInput contracts.LLMInputMaterial
}
func newGroundingResolver(references contracts.ReferenceSet) (*groundingResolver, error) {
@@ -109,15 +109,15 @@ func newGroundingResolver(references contracts.ReferenceSet) (*groundingResolver
if err != nil {
return nil, err
}
npcInteractions, err := prepareNPCInteractionInput(references)
npcOccurrences, err := prepareNPCOccurrenceInput(references)
if err != nil {
return nil, err
}
return &groundingResolver{
npcs: npcs,
scenes: scenes,
combatTurns: combatTurns,
npcInteractions: npcInteractions,
npcs: npcs,
scenes: scenes,
combatTurns: combatTurns,
npcOccurrences: npcOccurrences,
}, nil
}
@@ -136,14 +136,14 @@ func (r *groundingResolver) Resolve(references contracts.ReferenceSet) (groundin
if err != nil {
return grounding{}, err
}
npcInteractions, err := resolveInput(references, NPCInteractionReferenceSlot, r.npcInteractions, prepareNPCInteractionInput)
npcOccurrences, err := resolveInput(references, NPCOccurrenceReferenceSlot, r.npcOccurrences, prepareNPCOccurrenceInput)
if err != nil {
return grounding{}, err
}
return grounding{
npcInput: npcs.PromptInput(),
combatTurnInput: combatTurns,
npcInteractionInput: npcInteractions,
npcInput: npcs.PromptInput(),
combatTurnInput: combatTurns,
npcOccurrenceInput: npcOccurrences,
}, nil
}
@@ -188,9 +188,9 @@ func resolveInput(references contracts.ReferenceSet, slot string, seeded *contra
func (g grounding) PromptInputs() contracts.LLMInputSet {
return contracts.LLMInputSet{
NPCRegistryReferenceSlot: g.npcInput.Clone(),
CombatTurnReferenceSlot: g.combatTurnInput.Clone(),
NPCInteractionReferenceSlot: g.npcInteractionInput.Clone(),
NPCRegistryReferenceSlot: g.npcInput.Clone(),
CombatTurnReferenceSlot: g.combatTurnInput.Clone(),
NPCOccurrenceReferenceSlot: g.npcOccurrenceInput.Clone(),
}
}
@@ -212,22 +212,22 @@ func prepareCombatTurnInput(references contracts.ReferenceSet) (*contracts.LLMIn
return newPromptInput(CombatTurnReferenceSlot, content), nil
}
func prepareNPCInteractionInput(references contracts.ReferenceSet) (*contracts.LLMInputMaterial, error) {
item, ok, err := referenceItem(references, NPCInteractionReferenceSlot, interactioncodec.MediaType)
func prepareNPCOccurrenceInput(references contracts.ReferenceSet) (*contracts.LLMInputMaterial, error) {
item, ok, err := referenceItem(references, NPCOccurrenceReferenceSlot, occurrencecodec.MediaType)
if err != nil || !ok {
return nil, err
}
value, err := interactioncodec.New().Decode(item.Content)
value, err := occurrencecodec.New().Decode(item.Content)
if err != nil {
return nil, fmt.Errorf("decode NPC-interaction grounding: invalid approved NPC-interaction JSON")
return nil, fmt.Errorf("decode NPC-occurrence grounding: invalid approved NPC-occurrence JSON")
}
content, err := json.Marshal(struct {
Interactions []npcInteractionProjection `json:"npc_interactions"`
}{Interactions: projectNPCInteractions(value.Occurrences)})
Occurrences []npcOccurrenceProjection `json:"npc_occurrences"`
}{Occurrences: projectNPCOccurrences(value.Occurrences)})
if err != nil {
return nil, fmt.Errorf("encode NPC-interaction grounding: %w", err)
return nil, fmt.Errorf("encode NPC-occurrence grounding: %w", err)
}
return newPromptInput(NPCInteractionReferenceSlot, content), nil
return newPromptInput(NPCOccurrenceReferenceSlot, content), nil
}
func referenceItem(references contracts.ReferenceSet, slotName, expectedMediaType string) (contracts.ReferenceItem, bool, error) {
@@ -271,16 +271,16 @@ func projectCombatTurns(turns []dnd.CombatTurn) []combatTurnProjection {
return projection
}
type npcInteractionProjection struct {
type npcOccurrenceProjection struct {
Name string `json:"name"`
Kind dnd.NPCOccurrenceKind `json:"kind"`
}
func projectNPCInteractions(occurrences []dnd.NPCOccurrence) []npcInteractionProjection {
projection := make([]npcInteractionProjection, 0, len(occurrences))
func projectNPCOccurrences(occurrences []dnd.NPCOccurrence) []npcOccurrenceProjection {
projection := make([]npcOccurrenceProjection, 0, len(occurrences))
for _, occurrence := range occurrences {
if occurrence.Kind == dnd.NPCOccurrenceKindCombatOpponent {
projection = append(projection, npcInteractionProjection{Name: occurrence.Name, Kind: occurrence.Kind})
projection = append(projection, npcOccurrenceProjection{Name: occurrence.Name, Kind: occurrence.Kind})
}
}
return projection