Make D&D prompt asset manifests exact
This commit is contained in:
@@ -2,7 +2,9 @@ package shared
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"strings"
|
||||
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/llm"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/promptfs"
|
||||
@@ -11,39 +13,69 @@ import (
|
||||
//go:embed assets/prompts/*.md
|
||||
var embeddedAssets embed.FS
|
||||
|
||||
var sharedPromptFiles = []string{
|
||||
"common-dnd-system.md",
|
||||
"common-dnd-transcript.md",
|
||||
"common-dnd-references.md",
|
||||
"common-dnd-npcs.md",
|
||||
// PromptAssetManifest is the ordered set of assets that make up one prompt.
|
||||
// Module files are addressed in the owning module filesystem; shared files use
|
||||
// the names in sharedPromptPaths and are mounted beneath sharedassets.
|
||||
type PromptAssetManifest struct {
|
||||
ModuleDir string
|
||||
ModuleFiles []promptfs.ModulePromptFile
|
||||
SharedFiles []string
|
||||
}
|
||||
|
||||
func SharedPromptFiles() []promptfs.SharedPromptFile {
|
||||
files := make([]promptfs.SharedPromptFile, 0, len(sharedPromptFiles))
|
||||
for _, name := range sharedPromptFiles {
|
||||
var sharedPromptPaths = map[string]string{
|
||||
"common-dnd-system.md": "assets/prompts/common-dnd-system.md",
|
||||
"common-dnd-transcript.md": "assets/prompts/common-dnd-transcript.md",
|
||||
"common-dnd-references.md": "assets/prompts/common-dnd-references.md",
|
||||
"common-dnd-npcs.md": "assets/prompts/common-dnd-npcs.md",
|
||||
}
|
||||
|
||||
func (manifest PromptAssetManifest) PromptFS(moduleFS fs.FS) (fs.FS, error) {
|
||||
sharedFiles, err := resolveSharedPromptFiles(manifest.SharedFiles)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
moduleFiles := append([]promptfs.ModulePromptFile(nil), manifest.ModuleFiles...)
|
||||
return promptfs.ModulePromptFS(manifest.ModuleDir, moduleFS, moduleFiles, sharedFiles...)
|
||||
}
|
||||
|
||||
func (manifest PromptAssetManifest) Hash(moduleFS fs.FS) (string, error) {
|
||||
sharedFiles, err := resolveSharedPromptFiles(manifest.SharedFiles)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
parts := make([]llm.AssetHashPart, 0, len(manifest.ModuleFiles)+len(sharedFiles))
|
||||
for _, file := range manifest.ModuleFiles {
|
||||
parts = append(parts, llm.AssetHashPart{FS: moduleFS, Path: file.Path})
|
||||
}
|
||||
for _, file := range sharedFiles {
|
||||
parts = append(parts, llm.AssetHashPart{FS: file.FS, Path: file.Path})
|
||||
}
|
||||
return llm.HashAssets(parts)
|
||||
}
|
||||
|
||||
func resolveSharedPromptFiles(names []string) ([]promptfs.SharedPromptFile, error) {
|
||||
files := make([]promptfs.SharedPromptFile, 0, len(names))
|
||||
seen := make(map[string]struct{}, len(names))
|
||||
for _, name := range names {
|
||||
if name == "" {
|
||||
return nil, fmt.Errorf("shared prompt asset name must not be empty")
|
||||
}
|
||||
if strings.ContainsAny(name, `/\\`) {
|
||||
return nil, fmt.Errorf("shared prompt asset name %q must not contain path separators", name)
|
||||
}
|
||||
if _, ok := seen[name]; ok {
|
||||
return nil, fmt.Errorf("duplicate shared prompt asset name %q", name)
|
||||
}
|
||||
path, ok := sharedPromptPaths[name]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown shared prompt asset name %q", name)
|
||||
}
|
||||
seen[name] = struct{}{}
|
||||
files = append(files, promptfs.SharedPromptFile{
|
||||
Name: name,
|
||||
FS: embeddedAssets,
|
||||
Path: "assets/prompts/" + name,
|
||||
Path: path,
|
||||
})
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
func CommonHashParts() []llm.AssetHashPart {
|
||||
return []llm.AssetHashPart{
|
||||
{FS: embeddedAssets, Path: "assets/prompts/common-dnd-system.md"},
|
||||
{FS: embeddedAssets, Path: "assets/prompts/common-dnd-transcript.md"},
|
||||
}
|
||||
}
|
||||
|
||||
func ReferenceHashParts() []llm.AssetHashPart {
|
||||
return []llm.AssetHashPart{
|
||||
{FS: embeddedAssets, Path: "assets/prompts/common-dnd-references.md"},
|
||||
{FS: embeddedAssets, Path: "assets/prompts/common-dnd-npcs.md"},
|
||||
}
|
||||
}
|
||||
|
||||
func ModulePromptFS(moduleDir string, moduleFS fs.FS, files []promptfs.ModulePromptFile) (fs.FS, error) {
|
||||
return promptfs.ModulePromptFS(moduleDir, moduleFS, files, SharedPromptFiles()...)
|
||||
return files, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user