From 03761c97dd10cdd7a5533349f5ca3c93ea41b4d5 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Wed, 5 Aug 2026 00:40:47 +0000 Subject: [PATCH] Centralize NPC LLM assets --- .../prompts/dnd.npc_interactions.yaml | 0 .../npc-interactions}/prompts/instructions.md | 0 .../dnd/npc-interactions}/prompts/task.md | 0 .../schemas/dnd_npc_interactions_llm.v1.json | 0 .../dnd/npcs/extract}/prompts/dnd.npcs.yaml | 0 .../dnd/npcs/extract}/prompts/instructions.md | 0 .../dnd/npcs/extract}/prompts/task.md | 0 .../extract}/schemas/dnd_npcs_llm.v1.json | 0 .../dnd/npcs/normalize}/prompts/candidates.md | 0 .../prompts/dnd.npcs.normalize.yaml | 0 .../dnd/npcs/normalize}/prompts/task.md | 0 .../dnd/extract/npcinteractions/assets.go | 6 ---- .../extract/npcinteractions/prompt_assets.go | 35 +++++++++++++++---- .../dnd/extract/npcinteractions/schema.go | 8 +++-- internal/modules/dnd/extract/npcs/assets.go | 6 ---- .../modules/dnd/extract/npcs/prompt_assets.go | 35 +++++++++++++++---- internal/modules/dnd/extract/npcs/schema.go | 8 +++-- internal/modules/dnd/normalize/npcs/assets.go | 6 ---- .../dnd/normalize/npcs/prompt_assets.go | 29 ++++++++++++--- 19 files changed, 94 insertions(+), 39 deletions(-) rename {internal/modules/dnd/extract/npcinteractions/assets => assets/dnd/npc-interactions}/prompts/dnd.npc_interactions.yaml (100%) rename {internal/modules/dnd/extract/npcinteractions/assets => assets/dnd/npc-interactions}/prompts/instructions.md (100%) rename {internal/modules/dnd/extract/npcinteractions/assets => assets/dnd/npc-interactions}/prompts/task.md (100%) rename {internal/modules/dnd/extract/npcinteractions/assets => assets/dnd/npc-interactions}/schemas/dnd_npc_interactions_llm.v1.json (100%) rename {internal/modules/dnd/extract/npcs/assets => assets/dnd/npcs/extract}/prompts/dnd.npcs.yaml (100%) rename {internal/modules/dnd/extract/npcs/assets => assets/dnd/npcs/extract}/prompts/instructions.md (100%) rename {internal/modules/dnd/extract/npcs/assets => assets/dnd/npcs/extract}/prompts/task.md (100%) rename {internal/modules/dnd/extract/npcs/assets => assets/dnd/npcs/extract}/schemas/dnd_npcs_llm.v1.json (100%) rename {internal/modules/dnd/normalize/npcs/assets => assets/dnd/npcs/normalize}/prompts/candidates.md (100%) rename {internal/modules/dnd/normalize/npcs/assets => assets/dnd/npcs/normalize}/prompts/dnd.npcs.normalize.yaml (100%) rename {internal/modules/dnd/normalize/npcs/assets => assets/dnd/npcs/normalize}/prompts/task.md (100%) delete mode 100644 internal/modules/dnd/extract/npcinteractions/assets.go delete mode 100644 internal/modules/dnd/extract/npcs/assets.go delete mode 100644 internal/modules/dnd/normalize/npcs/assets.go diff --git a/internal/modules/dnd/extract/npcinteractions/assets/prompts/dnd.npc_interactions.yaml b/assets/dnd/npc-interactions/prompts/dnd.npc_interactions.yaml similarity index 100% rename from internal/modules/dnd/extract/npcinteractions/assets/prompts/dnd.npc_interactions.yaml rename to assets/dnd/npc-interactions/prompts/dnd.npc_interactions.yaml diff --git a/internal/modules/dnd/extract/npcinteractions/assets/prompts/instructions.md b/assets/dnd/npc-interactions/prompts/instructions.md similarity index 100% rename from internal/modules/dnd/extract/npcinteractions/assets/prompts/instructions.md rename to assets/dnd/npc-interactions/prompts/instructions.md diff --git a/internal/modules/dnd/extract/npcinteractions/assets/prompts/task.md b/assets/dnd/npc-interactions/prompts/task.md similarity index 100% rename from internal/modules/dnd/extract/npcinteractions/assets/prompts/task.md rename to assets/dnd/npc-interactions/prompts/task.md diff --git a/internal/modules/dnd/extract/npcinteractions/assets/schemas/dnd_npc_interactions_llm.v1.json b/assets/dnd/npc-interactions/schemas/dnd_npc_interactions_llm.v1.json similarity index 100% rename from internal/modules/dnd/extract/npcinteractions/assets/schemas/dnd_npc_interactions_llm.v1.json rename to assets/dnd/npc-interactions/schemas/dnd_npc_interactions_llm.v1.json diff --git a/internal/modules/dnd/extract/npcs/assets/prompts/dnd.npcs.yaml b/assets/dnd/npcs/extract/prompts/dnd.npcs.yaml similarity index 100% rename from internal/modules/dnd/extract/npcs/assets/prompts/dnd.npcs.yaml rename to assets/dnd/npcs/extract/prompts/dnd.npcs.yaml diff --git a/internal/modules/dnd/extract/npcs/assets/prompts/instructions.md b/assets/dnd/npcs/extract/prompts/instructions.md similarity index 100% rename from internal/modules/dnd/extract/npcs/assets/prompts/instructions.md rename to assets/dnd/npcs/extract/prompts/instructions.md diff --git a/internal/modules/dnd/extract/npcs/assets/prompts/task.md b/assets/dnd/npcs/extract/prompts/task.md similarity index 100% rename from internal/modules/dnd/extract/npcs/assets/prompts/task.md rename to assets/dnd/npcs/extract/prompts/task.md diff --git a/internal/modules/dnd/extract/npcs/assets/schemas/dnd_npcs_llm.v1.json b/assets/dnd/npcs/extract/schemas/dnd_npcs_llm.v1.json similarity index 100% rename from internal/modules/dnd/extract/npcs/assets/schemas/dnd_npcs_llm.v1.json rename to assets/dnd/npcs/extract/schemas/dnd_npcs_llm.v1.json diff --git a/internal/modules/dnd/normalize/npcs/assets/prompts/candidates.md b/assets/dnd/npcs/normalize/prompts/candidates.md similarity index 100% rename from internal/modules/dnd/normalize/npcs/assets/prompts/candidates.md rename to assets/dnd/npcs/normalize/prompts/candidates.md diff --git a/internal/modules/dnd/normalize/npcs/assets/prompts/dnd.npcs.normalize.yaml b/assets/dnd/npcs/normalize/prompts/dnd.npcs.normalize.yaml similarity index 100% rename from internal/modules/dnd/normalize/npcs/assets/prompts/dnd.npcs.normalize.yaml rename to assets/dnd/npcs/normalize/prompts/dnd.npcs.normalize.yaml diff --git a/internal/modules/dnd/normalize/npcs/assets/prompts/task.md b/assets/dnd/npcs/normalize/prompts/task.md similarity index 100% rename from internal/modules/dnd/normalize/npcs/assets/prompts/task.md rename to assets/dnd/npcs/normalize/prompts/task.md diff --git a/internal/modules/dnd/extract/npcinteractions/assets.go b/internal/modules/dnd/extract/npcinteractions/assets.go deleted file mode 100644 index dfde6ee..0000000 --- a/internal/modules/dnd/extract/npcinteractions/assets.go +++ /dev/null @@ -1,6 +0,0 @@ -package npcinteractions - -import "embed" - -//go:embed assets/schemas/dnd_npc_interactions_llm.v1.json assets/prompts/*.yaml assets/prompts/*.md -var embeddedAssets embed.FS diff --git a/internal/modules/dnd/extract/npcinteractions/prompt_assets.go b/internal/modules/dnd/extract/npcinteractions/prompt_assets.go index ad7ff0d..b468bff 100644 --- a/internal/modules/dnd/extract/npcinteractions/prompt_assets.go +++ b/internal/modules/dnd/extract/npcinteractions/prompt_assets.go @@ -2,8 +2,10 @@ package npcinteractions import ( "fmt" + "io/fs" "sync" + rootassets "gitea.maximumdirect.net/eric/notarius/assets" "gitea.maximumdirect.net/eric/notarius/internal/framework/llm" "gitea.maximumdirect.net/eric/notarius/internal/framework/promptfs" "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared" @@ -14,9 +16,9 @@ const promptAssetRoot = "assets/prompts" var promptAssetManifest = shared.PromptAssetManifest{ ModuleDir: "dnd.npc_interactions", ModuleFiles: []promptfs.ModulePromptFile{ - {Name: "dnd.npc_interactions.yaml", Path: "assets/prompts/dnd.npc_interactions.yaml"}, - {Name: "task.md", Path: "assets/prompts/task.md"}, - {Name: "instructions.md", Path: "assets/prompts/instructions.md"}, + {Name: "dnd.npc_interactions.yaml", Path: "prompts/dnd.npc_interactions.yaml"}, + {Name: "task.md", Path: "prompts/task.md"}, + {Name: "instructions.md", Path: "prompts/instructions.md"}, }, SharedFiles: []string{ "common-dnd-system.md", @@ -28,20 +30,41 @@ var promptAssetManifest = shared.PromptAssetManifest{ }, } +func moduleAssetFS() (fs.FS, error) { + assets, err := fs.Sub(rootassets.FS(), "dnd/npc-interactions") + if err != nil { + return nil, fmt.Errorf("scope NPC-interaction assets: %w", err) + } + return assets, nil +} + func RegisterPromptAssets(registry *llm.AssetRegistry) error { - promptFS, err := promptAssetManifest.PromptFS(embeddedAssets) + assets, err := moduleAssetFS() + if err != nil { + return err + } + promptFS, err := promptAssetManifest.PromptFS(assets) if err != nil { return fmt.Errorf("prepare NPC-interaction prompt assets: %w", err) } if err := registry.RegisterPromptFS(promptFS, promptAssetRoot); err != nil { return err } - return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas") + schemas, err := fs.Sub(assets, "schemas") + if err != nil { + return fmt.Errorf("scope NPC-interaction schemas: %w", err) + } + return registry.RegisterSchemaFS(schemas, ".") } func promptAssetMetadata() (string, error) { promptAssetHashOnce.Do(func() { - promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(embeddedAssets) + assets, err := moduleAssetFS() + if err != nil { + promptAssetHashErr = err + return + } + promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(assets) }) return promptAssetHash, promptAssetHashErr } diff --git a/internal/modules/dnd/extract/npcinteractions/schema.go b/internal/modules/dnd/extract/npcinteractions/schema.go index dd50fb8..4210c40 100644 --- a/internal/modules/dnd/extract/npcinteractions/schema.go +++ b/internal/modules/dnd/extract/npcinteractions/schema.go @@ -11,11 +11,15 @@ const ( ) func loadResponseSchema() (llm.ResponseSchema, error) { - return llm.LoadResponseSchema(embeddedAssets, llm.ResponseSchemaDefinition{ + assets, err := moduleAssetFS() + if err != nil { + return llm.ResponseSchema{}, err + } + return llm.LoadResponseSchema(assets, llm.ResponseSchemaDefinition{ Key: ResponseSchemaKey, ID: ResponseSchemaID, Version: SchemaVersion, Name: ResponseSchemaName, - AssetPath: "assets/schemas/dnd_npc_interactions_llm.v1.json", + AssetPath: "schemas/dnd_npc_interactions_llm.v1.json", }) } diff --git a/internal/modules/dnd/extract/npcs/assets.go b/internal/modules/dnd/extract/npcs/assets.go deleted file mode 100644 index e4b65d1..0000000 --- a/internal/modules/dnd/extract/npcs/assets.go +++ /dev/null @@ -1,6 +0,0 @@ -package npcs - -import "embed" - -//go:embed assets/schemas/dnd_npcs_llm.v1.json assets/prompts/*.yaml assets/prompts/*.md -var embeddedAssets embed.FS diff --git a/internal/modules/dnd/extract/npcs/prompt_assets.go b/internal/modules/dnd/extract/npcs/prompt_assets.go index d145a84..e01fc75 100644 --- a/internal/modules/dnd/extract/npcs/prompt_assets.go +++ b/internal/modules/dnd/extract/npcs/prompt_assets.go @@ -2,8 +2,10 @@ package npcs import ( "fmt" + "io/fs" "sync" + rootassets "gitea.maximumdirect.net/eric/notarius/assets" "gitea.maximumdirect.net/eric/notarius/internal/framework/llm" "gitea.maximumdirect.net/eric/notarius/internal/framework/promptfs" "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared" @@ -14,9 +16,9 @@ const promptAssetRoot = "assets/prompts" var promptAssetManifest = shared.PromptAssetManifest{ ModuleDir: "dnd.npcs", ModuleFiles: []promptfs.ModulePromptFile{ - {Name: "dnd.npcs.yaml", Path: "assets/prompts/dnd.npcs.yaml"}, - {Name: "task.md", Path: "assets/prompts/task.md"}, - {Name: "instructions.md", Path: "assets/prompts/instructions.md"}, + {Name: "dnd.npcs.yaml", Path: "prompts/dnd.npcs.yaml"}, + {Name: "task.md", Path: "prompts/task.md"}, + {Name: "instructions.md", Path: "prompts/instructions.md"}, }, SharedFiles: []string{ "common-dnd-system.md", @@ -27,20 +29,41 @@ var promptAssetManifest = shared.PromptAssetManifest{ }, } +func moduleAssetFS() (fs.FS, error) { + assets, err := fs.Sub(rootassets.FS(), "dnd/npcs/extract") + if err != nil { + return nil, fmt.Errorf("scope NPC extraction assets: %w", err) + } + return assets, nil +} + func RegisterPromptAssets(registry *llm.AssetRegistry) error { - promptFS, err := promptAssetManifest.PromptFS(embeddedAssets) + assets, err := moduleAssetFS() + if err != nil { + return err + } + promptFS, err := promptAssetManifest.PromptFS(assets) if err != nil { return fmt.Errorf("prepare NPC prompt assets: %w", err) } if err := registry.RegisterPromptFS(promptFS, promptAssetRoot); err != nil { return err } - return registry.RegisterSchemaFS(embeddedAssets, "assets/schemas") + schemas, err := fs.Sub(assets, "schemas") + if err != nil { + return fmt.Errorf("scope NPC extraction schemas: %w", err) + } + return registry.RegisterSchemaFS(schemas, ".") } func promptAssetMetadata() (string, error) { promptAssetHashOnce.Do(func() { - promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(embeddedAssets) + assets, err := moduleAssetFS() + if err != nil { + promptAssetHashErr = err + return + } + promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(assets) }) return promptAssetHash, promptAssetHashErr } diff --git a/internal/modules/dnd/extract/npcs/schema.go b/internal/modules/dnd/extract/npcs/schema.go index 2ca9c4a..3ed4c70 100644 --- a/internal/modules/dnd/extract/npcs/schema.go +++ b/internal/modules/dnd/extract/npcs/schema.go @@ -11,11 +11,15 @@ const ( ) func loadResponseSchema() (llm.ResponseSchema, error) { - return llm.LoadResponseSchema(embeddedAssets, llm.ResponseSchemaDefinition{ + assets, err := moduleAssetFS() + if err != nil { + return llm.ResponseSchema{}, err + } + return llm.LoadResponseSchema(assets, llm.ResponseSchemaDefinition{ Key: ResponseSchemaKey, ID: ResponseSchemaID, Version: SchemaVersion, Name: ResponseSchemaName, - AssetPath: "assets/schemas/dnd_npcs_llm.v1.json", + AssetPath: "schemas/dnd_npcs_llm.v1.json", }) } diff --git a/internal/modules/dnd/normalize/npcs/assets.go b/internal/modules/dnd/normalize/npcs/assets.go deleted file mode 100644 index 7423e70..0000000 --- a/internal/modules/dnd/normalize/npcs/assets.go +++ /dev/null @@ -1,6 +0,0 @@ -package npcs - -import "embed" - -//go:embed assets/prompts/*.yaml assets/prompts/*.md -var embeddedAssets embed.FS diff --git a/internal/modules/dnd/normalize/npcs/prompt_assets.go b/internal/modules/dnd/normalize/npcs/prompt_assets.go index 2494382..957ef00 100644 --- a/internal/modules/dnd/normalize/npcs/prompt_assets.go +++ b/internal/modules/dnd/normalize/npcs/prompt_assets.go @@ -2,8 +2,10 @@ package npcs import ( "fmt" + "io/fs" "sync" + rootassets "gitea.maximumdirect.net/eric/notarius/assets" "gitea.maximumdirect.net/eric/notarius/internal/framework/llm" "gitea.maximumdirect.net/eric/notarius/internal/framework/promptfs" "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared" @@ -14,9 +16,9 @@ const promptAssetRoot = "assets/prompts" var promptAssetManifest = shared.PromptAssetManifest{ ModuleDir: PromptID, ModuleFiles: []promptfs.ModulePromptFile{ - {Name: "dnd.npcs.normalize.yaml", Path: "assets/prompts/dnd.npcs.normalize.yaml"}, - {Name: "task.md", Path: "assets/prompts/task.md"}, - {Name: "candidates.md", Path: "assets/prompts/candidates.md"}, + {Name: "dnd.npcs.normalize.yaml", Path: "prompts/dnd.npcs.normalize.yaml"}, + {Name: "task.md", Path: "prompts/task.md"}, + {Name: "candidates.md", Path: "prompts/candidates.md"}, }, SharedFiles: []string{ "common-dnd-system.md", @@ -25,8 +27,20 @@ var promptAssetManifest = shared.PromptAssetManifest{ }, } +func moduleAssetFS() (fs.FS, error) { + assets, err := fs.Sub(rootassets.FS(), "dnd/npcs/normalize") + if err != nil { + return nil, fmt.Errorf("scope NPC normalization assets: %w", err) + } + return assets, nil +} + func RegisterPromptAssets(registry *llm.AssetRegistry) error { - promptFS, err := promptAssetManifest.PromptFS(embeddedAssets) + assets, err := moduleAssetFS() + if err != nil { + return err + } + promptFS, err := promptAssetManifest.PromptFS(assets) if err != nil { return fmt.Errorf("prepare NPC normalization prompt assets: %w", err) } @@ -35,7 +49,12 @@ func RegisterPromptAssets(registry *llm.AssetRegistry) error { func promptAssetMetadata() (string, error) { promptAssetHashOnce.Do(func() { - promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(embeddedAssets) + assets, err := moduleAssetFS() + if err != nil { + promptAssetHashErr = err + return + } + promptAssetHash, promptAssetHashErr = promptAssetManifest.Hash(assets) }) return promptAssetHash, promptAssetHashErr }