Move DnD shared prompt assets into helper package
This commit is contained in:
@@ -16,7 +16,6 @@ import (
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/merge/appendorder"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/normalize/noop"
|
||||
jsonoutput "gitea.maximumdirect.net/eric/notarius/internal/modules/output/json"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/sharedassets"
|
||||
)
|
||||
|
||||
func productionRegistries() (pipeline.Registries, error) {
|
||||
@@ -63,9 +62,6 @@ func productionCatalog() (pipeline.ModuleCatalog, error) {
|
||||
|
||||
func productionPromptAssets() (*llm.AssetRegistry, error) {
|
||||
registry := llm.NewAssetRegistry()
|
||||
if err := sharedassets.Register(registry); err != nil {
|
||||
return nil, fmt.Errorf("register shared dnd prompt assets: %w", err)
|
||||
}
|
||||
if err := scenes.RegisterPromptAssets(registry); err != nil {
|
||||
return nil, fmt.Errorf("register dnd scenes prompt assets: %w", err)
|
||||
}
|
||||
|
||||
@@ -191,9 +191,6 @@ func TestProductionPromptAssetsRegisterAndPrepareDndPrompts(t *testing.T) {
|
||||
t.Fatalf("PromptFS() error = %v, want nil", err)
|
||||
}
|
||||
for _, name := range []string{
|
||||
"common-dnd-system.md",
|
||||
"common-dnd-transcript.md",
|
||||
"common-dnd-references.md",
|
||||
"dnd.scenes/dnd.scenes.yaml",
|
||||
"dnd.scenes/task.md",
|
||||
"dnd.scenes/instructions.md",
|
||||
|
||||
@@ -9,16 +9,17 @@ import (
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/llm"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/sharedassets"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/sharedassets/dnd"
|
||||
)
|
||||
|
||||
const scriptoriumPromptRoot = "assets/prompts"
|
||||
|
||||
func RegisterPromptAssets(registry *llm.AssetRegistry) error {
|
||||
promptFS, err := sharedassets.ModulePromptFS("dnd.scenes", embeddedAssets, []sharedassets.ModulePromptFile{
|
||||
promptFS, err := dnd.ModulePromptFS("dnd.scenes", embeddedAssets, []sharedassets.ModulePromptFile{
|
||||
{Name: "dnd.scenes.yaml", Path: "assets/prompts/dnd.scenes.yaml"},
|
||||
{Name: "task.md", Path: "assets/prompts/task.md"},
|
||||
{Name: "instructions.md", Path: "assets/prompts/instructions.md"},
|
||||
}, sharedassets.SharedPromptFiles()...)
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("prepare scene prompt assets: %w", err)
|
||||
}
|
||||
@@ -64,7 +65,7 @@ func scriptoriumPromptMetadata() (string, error) {
|
||||
{FS: embeddedAssets, Path: "assets/prompts/dnd.scenes.yaml"},
|
||||
{FS: embeddedAssets, Path: "assets/prompts/task.md"},
|
||||
{FS: embeddedAssets, Path: "assets/prompts/instructions.md"},
|
||||
}, append(sharedassets.CommonHashParts(), sharedassets.ReferenceHashParts()...)...)
|
||||
}, append(dnd.CommonHashParts(), dnd.ReferenceHashParts()...)...)
|
||||
scriptoriumPromptHash, scriptoriumPromptHashErr = llm.HashAssets(parts)
|
||||
})
|
||||
return scriptoriumPromptHash, scriptoriumPromptHashErr
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"time"
|
||||
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/llm"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/sharedassets"
|
||||
"gitea.maximumdirect.net/eric/scriptorium"
|
||||
)
|
||||
|
||||
@@ -90,9 +89,6 @@ func TestScriptoriumPromptDiagnosticsOmitRawMaterials(t *testing.T) {
|
||||
func prepareScenesPrompt(t *testing.T, transcript []byte, players string, party string, glossary string) *scriptorium.PreparedRun {
|
||||
t.Helper()
|
||||
registry := llm.NewAssetRegistry()
|
||||
if err := sharedassets.Register(registry); err != nil {
|
||||
t.Fatalf("register shared prompt assets: %v", err)
|
||||
}
|
||||
if err := RegisterPromptAssets(registry); err != nil {
|
||||
t.Fatalf("register scene prompt assets: %v", err)
|
||||
}
|
||||
|
||||
@@ -9,16 +9,17 @@ import (
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/llm"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/sharedassets"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/sharedassets/dnd"
|
||||
)
|
||||
|
||||
const scriptoriumPromptRoot = "assets/prompts"
|
||||
|
||||
func RegisterPromptAssets(registry *llm.AssetRegistry) error {
|
||||
promptFS, err := sharedassets.ModulePromptFS("dnd.spells", embeddedAssets, []sharedassets.ModulePromptFile{
|
||||
promptFS, err := dnd.ModulePromptFS("dnd.spells", embeddedAssets, []sharedassets.ModulePromptFile{
|
||||
{Name: "dnd.spells.yaml", Path: "assets/prompts/dnd.spells.yaml"},
|
||||
{Name: "task.md", Path: "assets/prompts/task.md"},
|
||||
{Name: "instructions.md", Path: "assets/prompts/instructions.md"},
|
||||
}, sharedassets.SharedPromptFiles()...)
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("prepare spell prompt assets: %w", err)
|
||||
}
|
||||
@@ -64,7 +65,7 @@ func scriptoriumPromptMetadata() (string, error) {
|
||||
{FS: embeddedAssets, Path: "assets/prompts/dnd.spells.yaml"},
|
||||
{FS: embeddedAssets, Path: "assets/prompts/task.md"},
|
||||
{FS: embeddedAssets, Path: "assets/prompts/instructions.md"},
|
||||
}, append(sharedassets.CommonHashParts(), sharedassets.ReferenceHashParts()...)...)
|
||||
}, append(dnd.CommonHashParts(), dnd.ReferenceHashParts()...)...)
|
||||
scriptoriumPromptHash, scriptoriumPromptHashErr = llm.HashAssets(parts)
|
||||
})
|
||||
return scriptoriumPromptHash, scriptoriumPromptHashErr
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/llm"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/sharedassets"
|
||||
"gitea.maximumdirect.net/eric/scriptorium"
|
||||
)
|
||||
|
||||
@@ -140,9 +139,6 @@ func TestScriptoriumPromptDiagnosticsOmitRawMaterials(t *testing.T) {
|
||||
func prepareSpellsPrompt(t *testing.T, transcript []byte, players string, party string, glossary string) *scriptorium.PreparedRun {
|
||||
t.Helper()
|
||||
registry := llm.NewAssetRegistry()
|
||||
if err := sharedassets.Register(registry); err != nil {
|
||||
t.Fatalf("register shared prompt assets: %v", err)
|
||||
}
|
||||
if err := RegisterPromptAssets(registry); err != nil {
|
||||
t.Fatalf("register spell prompt assets: %v", err)
|
||||
}
|
||||
|
||||
@@ -1,28 +1,26 @@
|
||||
package sharedassets
|
||||
package dnd
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"io/fs"
|
||||
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/llm"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/sharedassets"
|
||||
)
|
||||
|
||||
//go:embed assets/prompts/*.md
|
||||
var embeddedAssets embed.FS
|
||||
|
||||
var commonDNDPromptFiles = []string{
|
||||
var sharedPromptFiles = []string{
|
||||
"common-dnd-system.md",
|
||||
"common-dnd-transcript.md",
|
||||
"common-dnd-references.md",
|
||||
}
|
||||
|
||||
func Register(registry *llm.AssetRegistry) error {
|
||||
return registry.RegisterPromptFS(embeddedAssets, "assets/prompts")
|
||||
}
|
||||
|
||||
func SharedPromptFiles() []SharedPromptFile {
|
||||
files := make([]SharedPromptFile, 0, len(commonDNDPromptFiles))
|
||||
for _, name := range commonDNDPromptFiles {
|
||||
files = append(files, SharedPromptFile{
|
||||
func SharedPromptFiles() []sharedassets.SharedPromptFile {
|
||||
files := make([]sharedassets.SharedPromptFile, 0, len(sharedPromptFiles))
|
||||
for _, name := range sharedPromptFiles {
|
||||
files = append(files, sharedassets.SharedPromptFile{
|
||||
Name: name,
|
||||
FS: embeddedAssets,
|
||||
Path: "assets/prompts/" + name,
|
||||
@@ -43,3 +41,7 @@ func ReferenceHashParts() []llm.AssetHashPart {
|
||||
{FS: embeddedAssets, Path: "assets/prompts/common-dnd-references.md"},
|
||||
}
|
||||
}
|
||||
|
||||
func ModulePromptFS(moduleDir string, moduleFS fs.FS, files []sharedassets.ModulePromptFile) (fs.FS, error) {
|
||||
return sharedassets.ModulePromptFS(moduleDir, moduleFS, files, SharedPromptFiles()...)
|
||||
}
|
||||
87
internal/modules/sharedassets/dnd/assets_test.go
Normal file
87
internal/modules/sharedassets/dnd/assets_test.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package dnd
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/llm"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/sharedassets"
|
||||
)
|
||||
|
||||
func TestSharedPromptFilesReturnsNewSlice(t *testing.T) {
|
||||
first := SharedPromptFiles()
|
||||
second := SharedPromptFiles()
|
||||
|
||||
if len(first) != 3 || len(second) != 3 {
|
||||
t.Fatalf("SharedPromptFiles() lengths = %d and %d, want 3", len(first), len(second))
|
||||
}
|
||||
first[0].Name = "changed.md"
|
||||
if second[0].Name != "common-dnd-system.md" {
|
||||
t.Fatalf("SharedPromptFiles() reused descriptor slice: %#v", second)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSharedPromptFilesReferenceEmbeddedAssets(t *testing.T) {
|
||||
for _, file := range SharedPromptFiles() {
|
||||
if file.FS == nil {
|
||||
t.Fatalf("SharedPromptFiles() descriptor %q has nil FS", file.Name)
|
||||
}
|
||||
if _, err := fs.ReadFile(file.FS, file.Path); err != nil {
|
||||
t.Fatalf("ReadFile(%q) error = %v, want nil", file.Path, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHashPartsReferenceSharedPrompts(t *testing.T) {
|
||||
assertHashParts(t, "common", CommonHashParts(), []string{
|
||||
"assets/prompts/common-dnd-system.md",
|
||||
"assets/prompts/common-dnd-transcript.md",
|
||||
})
|
||||
assertHashParts(t, "reference", ReferenceHashParts(), []string{
|
||||
"assets/prompts/common-dnd-references.md",
|
||||
})
|
||||
|
||||
for _, part := range append(CommonHashParts(), ReferenceHashParts()...) {
|
||||
if _, err := fs.ReadFile(part.FS, part.Path); err != nil {
|
||||
t.Fatalf("ReadFile(%q) error = %v, want nil", part.Path, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func assertHashParts(t *testing.T, name string, parts []llm.AssetHashPart, want []string) {
|
||||
t.Helper()
|
||||
if len(parts) != len(want) {
|
||||
t.Fatalf("%s hash parts length = %d, want %d", name, len(parts), len(want))
|
||||
}
|
||||
for i, part := range parts {
|
||||
if part.Path != want[i] {
|
||||
t.Fatalf("%s hash part %d path = %q, want %q", name, i, part.Path, want[i])
|
||||
}
|
||||
if part.FS == nil {
|
||||
t.Fatalf("%s hash part %d has nil FS", name, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestModulePromptFSMountsDNDSharedPrompts(t *testing.T) {
|
||||
fsys, err := ModulePromptFS("dnd.test", fstest.MapFS{
|
||||
"assets/prompts/dnd.test.yaml": {Data: []byte("id: dnd.test")},
|
||||
}, []sharedassets.ModulePromptFile{
|
||||
{Name: "dnd.test.yaml", Path: "assets/prompts/dnd.test.yaml"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("ModulePromptFS() error = %v, want nil", err)
|
||||
}
|
||||
|
||||
for _, path := range []string{
|
||||
"assets/prompts/dnd.test/dnd.test.yaml",
|
||||
"assets/prompts/dnd.test/sharedassets/common-dnd-system.md",
|
||||
"assets/prompts/dnd.test/sharedassets/common-dnd-transcript.md",
|
||||
"assets/prompts/dnd.test/sharedassets/common-dnd-references.md",
|
||||
} {
|
||||
if _, err := fs.ReadFile(fsys, path); err != nil {
|
||||
t.Fatalf("ReadFile(%q) error = %v, want nil", path, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user